I'm trying to disable ctor that has non-std::string constructible type. My 1st attempt was like this :
#include <iostream> struct A { template <typename U, typename = typename std::enable_if<std::is_constructible<std::string, U>::value>::type> A(U&& val) { std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl; } template <typename U, typename = typename std::enable_if<not std::is_constructible<std::string, U>::value>::type> A(U&& val) { std::cout << "A(int&& val)" << val << std::endl; } }; int main() { A a1(1); A a2("hello"); A a3(std::string("hello")); } But compilation fails in line
A a1(1);
with the following error message :
error C2535: 'A::A(U &&)': member function already defined or declared (live example).
That means, that both conditions for SFINAE succeeded and both ctors are used.
I moved on and tried the following approach :
#include <iostream> struct A { template <typename U> A(U&& val, typename std::enable_if<std::is_constructible<std::string, U>::value>::type* = nullptr) { std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl; } template <typename U> A(U&& val, typename std::enable_if<not std::is_constructible<std::string, U>::value>::type* = nullptr) { std::cout << "A(int&& val)" << val << std::endl; } }; int main() { A a1(1); A a2("hello"); A a3(std::string("hello")); } Luckily it compiles and works fine (live example).
So far, Im pretty fine with the 2nd solution but I don't really understand why the 1st approach with enabling/disabling ctor using templated parameter doesn't work.