我正在编写一个库,其中每个值类型都可以使用to_string()
转换为字符串。免费功能。
我想启用std::ostream& operator<<(std::ostream&, _)
适用于所有类型 T
其中to_string(T)
已验证。这是我的尝试:
namespace mylibrary {
// All my types are declared in the `mylibrary` namespace so that ADL is happy.
template <typename T>
inline std::string to_string(const T& value) {
// Return a string for value. Doesn't really matter how.
}
template <typename T>
inline std::ostream& operator<<(std::ostream& os, const T& value) {
return os << to_string(value);
}
}
这实际上有效......但有点太好了:在解析 os << to_string(value)
时我的模板operator<<()
甚至被选为 std::string
的候选者不幸的是,这使得调用不明确并最终导致编译器错误。
我尝试使用std::enable_if<>
有条件地禁用我的 operator<<
但遗憾的是我无法得到可以编译的东西。
如何限制我的 operator<<()
对于 to_string(T)
的类型是一个有效的表达式吗?
或者,有没有办法限制我的 operator<<()
对于我的命名空间中定义的类型?
最佳答案
您可以使用表达式-SFINAE 来限制模板重载集。例如这样:
#include <string>
#include <type_traits>
template <typename> using void_t = void;
template <typename T, typename = void_t<decltype(to_string(std::declval<T>()))>>
std::ostream& operator<<(std::ostream& os, const T& value) {
return os << to_string(value);
}
(您可能应该以某种方式将其包装起来,以免公共(public)模板中出现可见的第二个模板参数;用户会发现并滥用它。)
关于c++ - 如果存在专门化,如何限制模板化函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30407762/