c++ - 如何将 C++ 概念与 type_traits 结合使用?

标签 c++ c++20 typetraits c++-concepts

我想抽象类型接口(interface),我很难在两种 C++ 概念和 type_traits 之间做出决定。考虑以下场景:

template <typename T>
int foo(const T& t) { return t.size() + t.size(); }

类型T要求提供int T::size() const .为了创建更好的错误消息,增加客户端用户定义类型的可用性,并为他提供一个明确定义的可接受类型必须具备的能力的列表,可以引入一个概念:

template <typename T>
concept SizeHaving = requires(T t) {
    t.size();
}

template <SizeHaving T>
int foo(const T& t) { return t.size() + t.size(); }

但是,如果客户端类型原则上 可以实现这个概念,但在技术上不能实现(并且不能更改,因为它可能是第三方库的一部分)怎么办? type_trait 可以提供帮助:

struct Special {
   int Dimension() const; // logically identical to size(), but a different name
};

template <typename T>
struct Type_traits {
    static int size(const T& t) { return t.size(); }
};

template <> // user can provide the specialization for the custom type
struct Type_traits<Special> {
    static int size(const Special& c) { return c.Dimension(); }
};

template <typename T>
int foo(const T& t) {
    return Type_traits<T>::size(t) + Type_traits<T>::size(t);
}

如果标准执行Type_trait不适合自定义类型(并且没有提供专门化),将会再次出现相当不幸的错误消息。 我怎样才能将概念融入游戏中? 我试过的是

template <typename T>
concept SizeHaving = requires(T t) {
    Type_traits<T>::size(t);
}

但是表达式约束在技术上对任何类型都满足,无论是Type_traits<T>::size()可以显式实例化或不实例化,使这个概念变得无用。我能做什么?

最佳答案

你也可以限制你的特质:

template <typename T>
concept SizeHaving = requires(const T& t) {
    t.size(t);
};

template <typename T>
struct Type_traits
{
    auto size(const T& t) requires(SizeHaving<T>) { return t.size(); }
};

template <typename T>
concept TraitSizeHaving = requires(T t) {
    Type_traits<T>::size(t);
};

template <TraitSizeHaving T>
int foo(const T& t) {
    return Type_traits<T>::size(t) + Type_traits<T>::size(t);
}

然后专门针对您的自定义类型:

struct Special {
   int Dimension() const; // logically identical to size(), but a different name
};

template <> // user can provide the specialization for the custom type
struct Type_traits<Special> {
    static int size(const Special& c) { return c.Dimension(); }
};

Demo .

备注:requires(SizeHaving<T>)应该在成员上完成,而不是在类上完成,以允许类的特化。

关于c++ - 如何将 C++ 概念与 type_traits 结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65562113/

相关文章:

c++ - WinSock2.h 中的重新定义错误

c++ - 如何使用编译数据库为文件生成 LLVM 位码?

c++ - 常量整数和常量求值

c++ - 是否可以根据分配对象的类型特征覆盖全局 new 运算符?

c++ - 支持 g++ 中的类型属性

c++ - 如何检查引用是否为 const?

c++ - 代码未编译 - 最终进入 xmemory

c# - 将 Windows 数据类型映射到 .NET

c++ - 除了概念之外,在类型约束中禁止类型特征的理由是什么?

c++ - 为什么 `std::reference_wrapper` 在 c++17 中弃用并在 c++20 中删除?