I've done some looking around, but was unable to find a solution to my specific problem.
I have the code:
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, std::string>::type
convertToString(const T argument) { return std::to_string(argument); }
std::string convertToString(std::string string);
What the code is supposed to do: Use the template version for any numeric type (int, float, double and also ENum) and use the std::string version for anything else.
The code itself compiles fine, however when I pass the function a class, which has a operator const char *
overload (which is a viable constructor for std::string
), it throws me the following bulk of messages:
no matching function for call to 'SQL_Connection::convertToString(ClassName &)’
candidate: template<class T> typename std::enable_if<(std::is_arithmetic<_Tp>::value || std::is_enum<_Tp>::value), std::__cxx11::basic_string<char> >::type convertToString(T)
convertToString(const T argument) { return std::to_string(argument); }
^~~~~~~~~~~~~~~
template argument deduction/substitution failed:
In substitution of ‘template<class T> typename std::enable_if<(std::is_arithmetic<_Tp>::value || std::is_enum<_Tp>::value), std::__cxx11::basic_string<char> >::type convertToString(T) [with T = ClassName]’:
I've been trying to wrap my head around enable_if
and what it does, but at this point I find myself stumped.
Why isn't it falling back to the std::string
overload, when it clearly is neither arithmetic nor an ENum?
If I explicitly convert the object to string or const char *, it works as expected.
Thank you very much for your help.
Additional info: I'm using C++11 and g++ 7.3.0 on an Ubuntu system.
Your usage of enable_if
is correct and the problem is not in the function template at all. The thing is that the following won't compile either:
std::string convertToString(std::string string);
struct Foo{
operator const char*(){...}
};
Foo foo;
converToString(foo);
The reason is that the compiler is only allowed to do 1 user-defined conversion per passed parameter to match function arguments. In this case it would have to do 2 - Foo->const char*
and const char*->std::string
.
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