c++ - 如果存在专门化,如何限制模板化函数?

标签 c++ c++11

我正在编写一个库,其中每个值类型都可以使用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/

相关文章:

c++ - 编译为架构 x64 的库在 Arm 架构中出现错误

c++ - 当类型包含具有给定名称和类型的静态变量时启用_if 函数

c++ - 在 C++11 中为嵌套循环返回 vector 的最佳实践

c++ - 在基类和派生类中 copy-and-swap

c++ - Variadic constexpr 类型选择器

c++ - 如何使输入成为我的代码的一部分?

c++ - Pthread 循环函数永远不会被调用

multithreading - 访问boost::asio::ip::tcp::socket时,C++ 11线程崩溃

c++ - 使交换更快、更容易使用和异常安全

c++ - 如何给类添加继承结构,引用 "enable_share_on_this"