Ale*_*uch 4 c++ templates sfinae enable-if
我目前正在尝试实现一个toString函数,该函数调用.toString()或std::to_string()取决于推导类型可用的函数
到目前为止,我有这个工作片段:
#include <iostream>
#include <string>
template <class T>
auto toString(const T& obj)
-> decltype(obj.toString(), std::string())
{
return obj.toString();
}
template <class T>
auto toString(const T& obj)
-> decltype(std::to_string(obj), std::string())
{
return std::to_string(obj);
}
template <class T>
auto toString(const T& obj)
-> decltype(std::string(obj))
{
return std::string(obj);
}
class Foo{
public:
std::string toString() const {
return "Hello";
}
};
int main()
{
Foo bar;
std::cout << toString(bar);
std::cout << toString(5);
std::cout << toString("Hello const char*");
}
Run Code Online (Sandbox Code Playgroud)
现在我想插入一个static_assert当上面的那些没有重载是可行的,因为旧的GCC版本的默认GCC错误消息不是很有用.
我如何检查是否.toString()也std::to_string()不可能T?
到目前为止,我没有发现任何的方法来检查,如果事情是不存在,只有周围的其他方法.我希望有人知道如何解决这个问题并感谢你的时间.
你需要引入一个比你现在拥有的更糟糕的重载,并删除它.您不需要检查这两个字符串函数是否都存在.
一种流行的方法是使用C风格的可变参数:
std::string toString(...) = delete;
Run Code Online (Sandbox Code Playgroud)
您还可以使用static_assert自定义错误消息:
class Dummy
{
public:
std::string toString() const;
private:
Dummy() = default;
};
template <typename... Ts>
auto toString(Ts...)
{
static_assert(std::is_same<std::tuple<Ts...>, std::tuple<Dummy>>::value, "neither std::to_str nor member toString() exists");
return "";
}
Run Code Online (Sandbox Code Playgroud)