概念可以用来对值和类型施加约束吗?

问题描述

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

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)

解决方法

如您的示例所示,如果您想将概念用作模板参数上的命名 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) > 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,4>;  // error: constraints not satisfied