概念可以用来限制值和类型吗?

AKL*_*AKL 6 c++ templates concept c++20

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

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

template<int v, the_concept1<v> t>
struct some_struct1{};
Run Code Online (Sandbox Code Playgroud)

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

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

template<int v1, the_concept2<v1> v2>
struct some_struct2{};
Run Code Online (Sandbox Code Playgroud)

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

error: ‘the_concept2’ does not constrain a type
Run Code Online (Sandbox Code Playgroud)

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

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

template<typename t, std::size_t ... v>
struct the_struct;
Run Code Online (Sandbox Code Playgroud)

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

dfr*_*fri 6

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

您仍然可以定义仅适用于例如非类型模板参数的概念,但是,只要您在允许这些的上下文中使用它;例如使用一个requires-clause:

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
Run Code Online (Sandbox Code Playgroud)

另一个应用于函数模板或类模板的成员函数的示例:

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
}
Run Code Online (Sandbox Code Playgroud)

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

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

template<typename t, std::size_t ... v>
struct the_struct;
Run Code Online (Sandbox Code Playgroud)

我需要一个概念来检查 eachv是否小于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, 1, 2, 4>;  // error: constraints not satisfied
Run Code Online (Sandbox Code Playgroud)

  • @AKL请注意,您的更新完全改变了您原来的问题;下次,如果您意识到原来的问题实际上没有描述您想知道的内容,您可能想问一个新问题(作为参考,请参阅元帖子 [如何处理不断变化的问题](https://meta.stackoverflow .com/questions/252113/))。这次,我扩展了上面的答案,以解决您问题的编辑问题。 (2认同)