简体   繁体   English

如何将 C++ 概念与 type_traits 一起使用?

[英]How can I use C++ concepts with type_traits?

I want to abstract type interfaces and I am having a hard time to decide between the two C++ means of concepts and type_traits.我想抽象类型接口,我很难在概念和 type_traits 的两种 C++ 方法之间做出决定。 Consider the follow scenario:考虑以下场景:

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

The type T is requested to provide int T::size() const .要求类型T提供int T::size() const For creating better error messages, increasing usability for user-defined types of the client and giving him a well-defined list of what an acceptable type must be capable of, a concept can be introduced:为了创建更好的错误消息,增加客户端用户定义类型的可用性并为他提供一个明确定义的可接受类型必须能够做什么的列表,可以引入一个概念:

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

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

But what if a client type in principle could fulfill the concept, but technically doesn't (and cannot be changed, as it may be part of a third-party library)?但是,如果客户端类型原则上可以实现概念,但技术上不能(并且无法更改,因为它可能是第三方库的一部分)怎么办? A type_trait could help out: 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);
}

If the standard implementation of Type_trait does not suit for a custom type (and no specialization is provided), there will be again rather unfortunate error messages.如果Type_trait的标准实现不适合自定义类型(并且没有提供专门化),则会再次出现相当不幸的错误消息。 How can I get concepts into the play?如何将概念融入游戏? What I've tried is我试过的是

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

but the expression constraint will be technically satisfied for any type, whether Type_traits<T>::size() can be explicitly instantiated or not, rendering this concept useless.但是对于任何类型,无论Type_traits<T>::size()是否可以显式实例化,从技术上讲,表达式约束都将得到满足,这使得这个概念毫无用处。 What can I do?我能做些什么?

You might also constraint your traits:你也可以限制你的特质:

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);
}

And then specialize for your custom type:然后专门针对您的自定义类型:

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 .演示

Note: requires(SizeHaving<T>) should be done on member, and not the class to allow specialization of the class.注意: requires(SizeHaving<T>)应该在成员上完成,而不是 class 以允许 class 的专业化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM