Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::to_string()没有模板化?_C++_Templates_Libstdc++ - Fatal编程技术网

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

C++ 为什么std::to_string()没有模板化?,c++,templates,libstdc++,C++,Templates,Libstdc++,如上所述,std::string不是一个模板函数,而是一个标准函数,它选择使用函数重载为不同类型提供此函数。我的问题是,在这种情况下,当模板/专业化似乎对我更有意义时,为什么要使用重载?如果标准定义了这样的东西: template <typename T> std::string std::to_string(const T& v); 模板 std::string std::to_string(常量T&v); 然后我们可以自由地为我们的程序中的任何类型添加专业化以符合这个

如上所述,
std::string
不是一个模板函数,而是一个标准函数,它选择使用函数重载为不同类型提供此函数。我的问题是,在这种情况下,当模板/专业化似乎对我更有意义时,为什么要使用重载?如果标准定义了这样的东西:
template <typename T>
std::string std::to_string(const T& v);
模板
std::string std::to_string(常量T&v);

然后我们可以自由地为我们的程序中的任何类型添加专业化以符合这个签名,因此C++将有一个统一的方式来将类型转换为人类可读字符串。为什么不这样做呢?当前设计背后的想法是什么

编辑1:

我对当前设计的主要批评是,不允许向
std
添加重载,因此我们不能编写类似
std:to\u字符串(用户定义类型的对象)
的内容,而必须依赖于定义
to\u字符串()
在他们自己的名称空间中,记住在何处使用他们的版本或
std
版本取决于他们处理的类型。。。这听起来让我头疼

我非常喜欢Python(或其他一些语言)的一点是,通过实现一些神奇的方法,您可以使自己的类型像本机类型一样工作。我认为这个问题的根本原因是,为什么C++不允许人们执行<代码> STD::toyStRung()/<代码>,以禁止它们随处符合同一个接口。 对于像
hash
to_string()
这样的常见事物,在语言/
stdlib
级别上使用一个接口,然后期望用户遵守该接口,而不是使用多个接口,不是更好吗

<>为什么C++不允许人们执行<代码> STD::toSype 为自己的类型

这就是ADL有用的地方。我们已经有了如何使用
std::swap
正确执行此操作的示例,这已经在许多代码库中成功完成:

template <typename T>
void swap_example(T & a, T & b) {
    using std::swap;
    swap(a, b);
}
如果命名空间
T
在中声明,并且有一个
to_string
函数,该函数可以接受
T常量&
参数,则这同样有效。例如:

namespace example {
    class Foo;

    std::string to_string(Foo const &);
}
to_string\u示例(example::Foo{})
将查找并使用相应的
example::to_string
函数


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

如果这真的让您头疼,您可以将ADL隐藏在项目中的实用功能后面:

template <typename T>
std::string adl_to_string(T const & x) {
    using std::to_string;
    return to_string(x);
}
模板
std::string adl_to_string(T const&x){
使用std::to_字符串;
返回到_字符串(x);
}

现在,您可以使用
adl_to_string(…)
而不是
std::to_string(…)
到处使用,而无需考虑它。

这听起来可能有点无聊,但是
std::to_string
的目的是像使用
sprintf
一样进行格式化,而
sprintf
只支持有限的一组类型这对于
std::to_string
也是如此。不需要将其作为模板


正如在该设计中详细解释的,该设计没有您认为它具有的限制。您仍然可以提供自己的
foo::to_字符串(foo::bar&)
,并且在使用适当的名称限定来启用ADL的代码中,您的重载将被调用。为此,无需将重载添加到
std

,如果愿意,也可以添加重载。重载还可以更好地用于参数相关的查找,因为可以将重载与参数类型放在同一命名空间中。另外,我不相信你可以在STD命名空间中专门化模板。@添加模板特化是允许更改“代码> STD< /Clord>命名空间的例外之一。人们为什么相信C++中的每一件小事都应该被模板化?从设计的角度来看,只有在可以为无限数量的任意类型指定函数的行为时,才有必要对函数进行模板化。除了它所使用的类型(基本数字类型)之外,标准无法明智地对任何其他类型执行此操作。它可以指定的集合是有限的,这意味着只对这些类型重载是合适的,而不是模板。您不需要将重载添加到
std
。它适用于
交换
,也适用于其他功能。你可以把过载放在任何地方,只要它被ADL发现,答案详细解释了这一点。你所看到的缺点并不存在
template <typename T>
std::string adl_to_string(T const & x) {
    using std::to_string;
    return to_string(x);
}