SFINAE与enable_if和重载

Ref*_*ium 9 c++ templates sfinae enable-if c++11

我已经环顾四周,但是无法找到解决我特定问题的方法。

我有代码:

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);
Run Code Online (Sandbox Code Playgroud)

代码应该做什么:将模板版本用于任何数字类型(int,float,double和ENum),并将std :: string版本用于其他任何类型。

代码本身可以很好地编译,但是当我向函数传递一个具有operator const char *重载的类(这是可行的构造函数std::string)时,它会向我抛出以下大量消息:

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]’:
Run Code Online (Sandbox Code Playgroud)

我一直在努力寻找解决方案enable_if,但现在我发现自己很沮丧。

std::string当它显然既不是算术也不是ENum时,为什么不回到超载呢?

如果我将对象明确转换为字符串或const char *,它将按预期工作。

非常感谢您的帮助。

附加信息:我在Ubuntu系统上使用C ++ 11和g ++ 7.3.0。

Qui*_*mby 8

您对的使用enable_if是正确的,问题根本不在功能模板中。问题是以下代码也不会编译:

std::string convertToString(std::string string);
struct Foo{
    operator const char*(){...}
};
Foo foo; 
converToString(foo);
Run Code Online (Sandbox Code Playgroud)

原因是编译器仅允许每个传递的参数进行1个用户定义的转换以匹配函数参数。在这种情况下,它必须做2- Foo->const char*const char*->std::string

  • @RefugnicEternium是的,事情发生了……错误消息有点误导,它显示了候选对象,而“ std converToString(str)”恰好不在其中,但这不是通常人在查看错误时会注意到的内容。 (2认同)