如何使用C++20 Concept实现类模板约束以替代SFINAE方案
你遇到的编译错误是语法使用错误导致的,C++20完全支持通过Concept实现类模板的约束特化。
错误原因
你两次写法都直接重复定义了MyClass的主模板,C++不允许同一个模板的主模板被多次定义。带约束的类模板分支需要以偏特化的形式声明,而非重复定义主模板。
正确实现方式
方式1:双约束特化实现(对应你第一种写法的需求)
#include <iostream> template<typename T> concept smallerThanPointer = sizeof(T) < sizeof(void*); template<typename T> concept notSmallerThanPointer = !smallerThanPointer<T>; // 仅声明一次无约束主模板 template<typename T> class MyClass; // 满足smallerThanPointer的特化版本,注意后缀<T>表示这是偏特化 template<smallerThanPointer T> class MyClass<T> { public: MyClass() { std::cout << "MyClass[smallerThanPointer]\n"; } }; // 满足notSmallerThanPointer的特化版本 template<notSmallerThanPointer T> class MyClass<T> { public: MyClass() { std::cout << "MyClass[...]\n"; } }; int main() { MyClass<int> c0; // 输出MyClass[smallerThanPointer] MyClass<int[8]> c1; // 输出MyClass[...] return 0; }
方式2:主模板做默认实现+单约束特化(对应你第二种写法的需求)
#include <iostream> template<typename T> concept smallerThanPointer = sizeof(T) < sizeof(void*); // 无约束主模板作为默认实现 template<typename T> class MyClass { public: MyClass() { std::cout << "MyClass[...]\n"; } }; // 仅对满足smallerThanPointer的类型做特化 template<smallerThanPointer T> class MyClass<T> { public: MyClass() { std::cout << "MyClass[smallerThanPointer]\n"; } }; int main() { MyClass<int> c0; MyClass<int[8]> c1; return 0; }
编译注意事项
GCC 11已完整支持该语法,编译时需要添加-std=c++20(或-std=gnu++20)编译参数开启C++20标准支持。
内容的提问来源于stack exchange,提问作者alexpanter
相关产品推荐
相关产品推荐

