【问题标题】:How can I use C++ concepts with type_traits?如何将 C++ 概念与 type_traits 结合使用?
【发布时间】:2021-01-04 11:41:52
【问题描述】:

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

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

但是对于 any 类型,无论Type_traits&lt;T&gt;::size() 是否可以显式实例化,在技术上都将满足表达式约束,从而使这个概念变得毫无用处。我能做什么?

【问题讨论】:

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


    【解决方案1】:

    你也可以限制你的特质:

    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&lt;T&gt;) 应该在成员上完成,而不是在允许类专业化的类上完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 2022-01-19
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多