【问题标题】:Can concepts be used to put a constraint on values as well as types?可以使用概念来限制值和类型吗?
【发布时间】:2020-09-19 22:27:46
【问题描述】:

概念可用于将类型约束作为模板参数,如下例所示:

template<typename t, int v>
concept the_concept1 = sizeof(t) > v;

template<int v, the_concept1<v> t>
struct some_struct1{};

我正在尝试使用类似的方法,其值如下例所示:

template<int v1, int v2>
concept the_concept2 = v1 > v2;

template<int v1, the_concept2<v1> v2>
struct some_struct2{};

但是使用 G++ 10 我收到以下错误消息:

error: ‘the_concept2’ does not constrain a type

所以我想知道是否可以使用概念来限制值?如果是,那我该怎么做呢?

编辑:我的最终目标是在声明中使用带有可变模板参数的模板结构的概念,例如:

template<typename t, std::size_t ... v>
struct the_struct;

我需要一个概念来检查每个v是否小于sizeof(t)

【问题讨论】:

    标签: c++ templates c++20 concept


    【解决方案1】:

    如果您想将概念用作模板参数上的命名 type 约束,如您的示例中所示,则该概念需要应用于 type 模板参数。

    您仍然可以定义仅适用于例如但是,非类型模板参数,只要您在允许这些的上下文中使用它;例如使用要求子句:

    template<int v1, int v2>
    concept the_concept2 = v1 > v2;
    
    template<int v1, int v2> requires the_concept2<v1, v2>
    struct some_struct2{};
    
    using valid = some_struct2<42, 41>;
    //using invalid = some_struct2<42, 42>; // constraints not satisfied
    

    另一个应用在函数模板或类模板的成员函数上的例子:

    template<int v1, int v2>
    concept the_concept2 = v1 > v2;
    
    template <int a, int b>
    void bar() requires the_concept2<a, b> {} 
    
    template <int a, int b>
    struct Foo {
        static void bar() requires the_concept2<a, b> {} 
    };
    
    int main() {
        bar<2, 1>();
        Foo<2, 1>::bar();
        //bar<2, 2>();      // candidate template ignored: constraints not satisfied
        //Foo<2, 2>::bar(); // invalid reference to function 'bar': constraints not satisfied
    }
    

    以下 OP 编辑​​(基本上提出了一个完全不同的问题)

    编辑:我的最终目标是在模板声明中使用这个概念 具有可变模板参数的结构,例如:

    template<typename t, std::size_t ... v>
    struct the_struct;
    

    我需要一个概念来检查每个v 是否小于sizeof(t)

    可以通过指定概念本身来申请在sizeof(T) &gt; v检查中使用参数包扩展扩展的可变参数非类型模板参数来实现:

    #include <cstddef>
    #include <cstdint>
    
    template<typename T, std::size_t... v>
    concept the_concept1 = (... && (sizeof(T) > v));
    
    template<typename T, std::size_t... vs> requires the_concept1<T, vs...>
    struct the_struct;
    
    using TypeOfSize4Bytes = uint32_t;
    
    using valid = the_struct<TypeOfSize4Bytes, 1, 3, 2, 1>;
    using also_valid = the_struct<TypeOfSize4Bytes>;
    //using invalid = the_struct<TypeOfSize4Bytes, 1, 2, 4>;  // error: constraints not satisfied
    

    【讨论】:

    • 也许std::integral_constant&lt;int, 42&gt; 超过wraps_42
    • @Caleth 我完全删除了该示例,感谢您的反馈!
    • 感谢您的回答,但我无法使用该解决方案。我更新了问题。请看一下。
    • @AKL 请注意,您的更新完全改变了您原来的问题;下次您可能想问一个新问题,如果您意识到您的原始问题实际上并未描述您想知道的内容(作为参考,请参阅元帖子How to deal with constant changing questions)。这次,我扩大了上面的答案,以解决您对问题的编辑。
    猜你喜欢
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多