I'm trying to select a constructor through SFINAE as following:
template<typename T>
class MyClass
{
public:
template<typename C, typename = std::enable_if_t<std::is_class<C>::value>>
MyClass(C) { }
template<typename C, typename = std::enable_if_t<std::is_pointer<C>::value>>
MyClass(C) { }
};
but the compiler complains with following error:
error C2535: 'MyClass::MyClass(C)': member function already defined or declared
without even instantiating the constructor.
I worked out a working but ugly solution which i don't want to use because of the extra unused parameter:
template<typename T>
class MyWorkingClass
{
public:
template<typename C>
MyWorkingClass(C, std::enable_if_t<std::is_class<C>::value>* = nullptr) { }
template<typename C>
MyWorkingClass(C, std::enable_if_t<std::is_pointer<C>::value>* = nullptr) { }
};
A short usage example is given here:
void* ptr = nullptr;
MyClass<int> mc1(ptr);
std::vector<int> vec;
MyClass<int> mc2(vec);
// Shall raise an error
// MyClass<int> mc2(0);
The traits std::is_pointer
and std::is_class
are just an example, the original traits are more complicated.
Is there a way to select the constructor through SFINAE without adding another parameter to the constructor (maybe very close to the first appproach)?
The problem is that the default values of arguments are not part of the template method signature. So you have two template<class C,class>ctor(c)
identical ctors.
template<class T>
struct MyClass {
template<class C,
std::enable_if_t<std::is_class<C>{}>* =nullptr
>
MyClass(C) { }
template<class C,
std::enable_if_t<std::is_pointer<C>{}>* =nullptr
>
MyClass(C) { }
};
here we use template value arguments of dependant type. They never conflict, as the type of the pointer template argument is dependant on the type argument.
Add one more (dummy) type template parameter:
template <typename C
, typename = std::enable_if_t<std::is_class<C>::value>>
MyClass(C) { }
template <typename C
, typename = std::enable_if_t<std::is_pointer<C>::value>
, typename = void>
// ~~~~~~~~~~~~~~^
MyClass(C) { }
DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With