具有 enable_if 和重载的 SFINAE

SFINAE with enable_if and overloading

我环顾四周,但找不到解决我的具体问题的方法。

我有代码:

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);

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

代码本身编译得很好,但是当我传递函数 class 时,它有一个 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]’:

我一直在努力思考 enable_if 及其作用,但此时我发现自己被难住了。

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

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

非常感谢您的帮助。

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

你对enable_if的用法是正确的,问题根本不在函数模板中。问题是以下内容也不会编译:

std::string convertToString(std::string string);
struct Foo{
    operator const char*(){...}
};
Foo foo; 
converToString(foo);

原因是编译器只允许对每个传递的参数进行 1 次 user-defined 转换以匹配函数参数。在这种情况下,它必须执行 2 - Foo->const char*const char*->std::string.