[英]Why is std::to_string() not templated?
如此处所述std::string
不是模板 function 而是标准选择使用 function 重载来为不同类型提供此 function。 我的问题是,在这种情况下,当模板/专业化似乎对我更有意义时,为什么要使用重载? 考虑一下,如果标准定义了这样的内容:
template <typename T>
std::string std::to_string(const T& v);
然后我们可以在我们的程序中自由地为任何类型添加特殊化以符合这个签名,因此 C++ 将有一个统一的方式将类型转换为人类可读的字符串。 为什么不这样做? 当前设计背后的想法是什么?
编辑1:
我对当前设计的主要批评是不允许向std
添加重载,因此我们不能编写任何类似std:to_string(object-that-is-of-user-defined-types)
东西,而不得不依靠在他们自己的命名空间中定义一个to_string()
并记住在哪里使用他们的版本或std
版本取决于他们正在处理的类型......这对我来说听起来很头疼。
我真正喜欢 Python(或其他一些语言)的一件事是,您可以通过实现一些魔术方法使自己的类型像本机类型一样工作。 我认为这个问题的根本原因是为什么 C++ 决定禁止人们为自己的类型实现std::to_string()
,从而禁止我们在任何地方都遵循相同的接口。
对于像hash
或to_string()
这样的常见事情,在语言/标准stdlib
级别上拥有一个接口然后期望用户遵守该接口而不是拥有多个接口不是更好吗?
为什么 C++ 决定禁止人们为自己的类型实现
std::to_string
这就是 ADL 有用的地方。 我们已经有了如何使用std::swap
正确执行此操作的示例,这已经在许多代码库中成功完成:
template <typename T>
void swap_example(T & a, T & b) {
using std::swap;
swap(a, b);
}
如果在其中声明的命名空间T
具有兼容的swap()
function,则此方法有效,而无需重载std::swap
。 我们可以用std::to_string
做同样的事情:
template <typename T>
void to_string_example(T const & x) {
using std::to_string;
to_string(x);
}
如果命名空间T
被声明为具有可以接受T const &
参数的to_string
function,这同样可以工作。 例如:
namespace example {
class Foo;
std::string to_string(Foo const &);
}
to_string_example(example::Foo{})
会找到并使用相应的example::to_string
function。
记住在哪里使用他们的版本或标准版本取决于他们正在处理的类型......这对我来说听起来很头疼。
如果这真的让您头疼,您可以在项目中将 ADL 隐藏在实用程序 function 后面:
template <typename T>
std::string adl_to_string(T const & x) {
using std::to_string;
return to_string(x);
}
现在您可以在任何地方使用adl_to_string(...)
而不是std::to_string(...)
而不必考虑它。
这可能听起来有点无聊,但std::to_string
的目的是像您使用过sprintf
一样进行格式化,因为sprintf
仅支持有限的一组类型,这对于std::to_string
也是如此。 无需将其设为模板。
正如此答案中详细解释的那样,设计没有您认为的限制。 您仍然可以提供自己的foo::to_string(foo::bar&)
并且在使用适当的名称限定来启用 ADL 的代码中将调用您的重载。 为此,没有必要向std
添加重载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.