首页 > 解决方案 > 使用 C++20 Concept 约束模板参数

问题描述

我想使用概念来替换当前使用 SFINAE (enable_if) 的设计。为了简化,我创建了一个更简单的示例,它显示了一个相同的问题:

template<typename T>
concept smallerThanPointer = sizeof(T) < sizeof(void*);

template<typename T>
concept notSmallerThanPointer = !smallerThanPointer<T>;


template<smallerThanPointer T>
class MyClass
{
 public:
    MyClass() { std::cout << "MyClass[smallerThanPointer]\n"; }
};

template<notSmallerThanPointer T>
class MyClass
{
 public:
    MyClass() { std::cout << "MyClass[...]\n"; }
};


int main()
{
    MyClass<int[8]> c1;

    return 0;
}

但是我的编译器(g++-11)不会接受这种语法,因为它认为我在重新声明MyClass. 这个例子也是不可能的:

template<typename T>
class MyClass requires smallerThanPointer<T>
{
 public:
    MyClass() { std::cout << "MyClass[smallerThanPointer]\n"; }
};

template<typename T>
class MyClass
{
 public:
    MyClass() { std::cout << "MyClass[...]\n"; }
};

我在网上找到的所有带有概念的示例仅讨论如何将概念应用于函数参数。那么有可能与班级有关吗?

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

解决方案


约束的部分模板特化的正确语法应该是:

template<typename T>
concept smallerThanPointer = sizeof(T) < sizeof(void*);
    
template<class T>
class MyClass
{
public:
    MyClass() { std::cout << "MyClass[...]\n"; }
};
    
template<class T> requires smallerThanPointer<T>
class MyClass<T>
{
public:
    MyClass() { std::cout << "MyClass[smallerThanPointer]\n"; }
};

演示。


推荐阅读