gpt4 book ai didi

c++ - 如何使用 C++ 模板执行正式协议(protocol)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:34:27 26 4
gpt4 key购买 nike

当使用 template style 固有的编译时鸭子类型时, 有什么方法可以强制要求模板参数实现具有特定签名的特定方法?

struct ProtocolT {
void g() const;
void h();
}

// I want the compiler to check that T conforms to ProtocolT
// that is, T must implement g() and h() rather than just g()
template <typename T>
void f(const T& x) {
x.g();
}

当然,即使没有这个,也有完美的类型安全:如果模板参数 T 没有在模板函数实现中使用的方法,编译器总是会报错。

但我发现明确声明 class T 必须具有某些 class ProtocolT 中指定的所有方法很有吸引力。它允许我在开发过程的早期通过要求 T 中我尚未在模板函数实现中使用的方法来约束设计。

即使我没有在 ProtocolT 中包含任何未使用的方法,我仍然认为当我需要编写一个可用作 T 的类时,经过验证的协议(protocol)一致性会有所帮助。 (当然,没有人阻止我编写 ProtocolT 用于文档目的,但是编译器不会验证 ProtocolT 至少包含所有必需的方法。)

最佳答案

您要查找的特征称为 concepts .它们目前是技术规范; GCC 有一个 concepts lite 的实现。

使用概念看起来像(我不太熟悉语法,所以它可能会略有不同):

template <typename T>
concept bool Protocol = requires(const T a, T b) {
{ a.g() } -> void;
{ b.h() } -> void;
};

void f(const Protocol& x) {
x.g();
}

但是,如果您想要一个可以立即使用的解决方案,您可以使用各种技术模拟概念。

您可以编写类型特征来检测函数是否按照您的要求执行。

您还可以使用 detection idiom ,它抽象了以前的技术,大大减少了样板代码。对于您的示例:

template <typename T>
using g_t = decltype(std::declval<const T&>().g());

template <typename T>
using h_t = decltype(std::declval<T&>().h());

template <typename T>
constexpr bool meets_protocol_v = std::experimental::is_detected_exact_v<void, g_t, T>
&& std::experimental::is_detected_exact_v<void, h_t, T>;

在使用它时,您可以是 SFINAE 友好型和 SFINAE 脱离 meets_protocol_v,或者您可以静态断言:

template <typename T>
void f(const T& x) {
static_assert(meets_protocol_v<T>, "Doesn't meet protocol");
x.g();
}

关于c++ - 如何使用 C++ 模板执行正式协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44912243/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com