I want to use concepts to replace a design which currently uses SFINAE (enable_if). To simplify, I have created a simpler example which shows an identical problem:
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;
}
But my compiler (g -11) will not accept this syntax because it thinks I'm redeclaring MyClass
. Also this example is not possible:
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"; }
};
All examples I have found online with concepts only discuss how to apply concepts to function parameters. So is it possible at all to do with a class?
CodePudding user response:
The correct syntax for the partial template specialization for constraints should be:
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"; }
};