为什么std::to_string()没有模板化

Why is std::to_string() not templated?

本文关键字:std to string 为什么      更新时间:2023-10-16

如前所述,std::string不是一个模板函数,而是标准选择使用函数重载为不同类型提供此函数。我的问题是,在这种情况下,当模板/专业化对我来说更有意义时,为什么要使用重载?考虑一下,如果标准定义了这样的东西:

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(),从而禁止我们在任何地方都遵循相同的接口。

对于像hashto_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()函数,则不需要重载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函数,则这同样有效。例如:

namespace example {
class Foo;
std::string to_string(Foo const &);
}

CCD_ 19将找到并使用相应的CCD_。


记住在哪里使用他们的版本或std版本取决于他们处理的类型。。。这听起来让我头疼。

如果这真的让你头疼,你可以把ADL隐藏在项目中的一个实用函数后面:

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添加过载。