简体   繁体   English

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

[英]Why is std::to_string() not templated?

As stated here std::string is not a template function but rather the standard choose to use function overloading to provide this function for different types.如此所述std::string不是模板 function 而是标准选择使用 function 重载来为不同类型提供此 function。 My question is why use overloading when template/specialisation seems to make more sense to me in this case?我的问题是,在这种情况下,当模板/专业化似乎对我更有意义时,为什么要使用重载? Consider that if the standard has defined something like this:考虑一下,如果标准定义了这样的内容:

template <typename T>
std::string std::to_string(const T& v);

Then we can freely add specialisation for any type in our program to conform to this signature, thus C++ will have a uniform way to transform types into human-readable strings.然后我们可以在我们的程序中自由地为任何类型添加特殊化以符合这个签名,因此 C++ 将有一个统一的方式将类型转换为人类可读的字符串。 Why not do this?为什么不这样做? What's the thinking behind the current design?当前设计背后的想法是什么?

Edit 1:编辑1:

The main critic I have for the current design is that adding an overload to std is not allowed so we can not write anything like std:to_string(object-that-is-of-user-defined-types) and has to fall back on defining a to_string() in their own namespace and remember where to use their version or the std version depends on the types they are dealing with... This sounds like a headache for me.我对当前设计的主要批评是不允许向std添加重载,因此我们不能编写任何类似std:to_string(object-that-is-of-user-defined-types)东西,而不得不依靠在他们自己的命名空间中定义一个to_string()并记住在哪里使用他们的版本或std版本取决于他们正在处理的类型......这对我来说听起来很头疼。

One thing I really liked about Python (or some other languages) is that you can make your own type work just like a native type by implementing some magic methods.我真正喜欢 Python(或其他一些语言)的一件事是,您可以通过实现一些魔术方法使自己的类型像本机类型一样工作。 I think what this question is fundamentally about is that why C++ decided to disallow people to implement std::to_string() for their own type and thus forbid us from conforming to the same interface everywhere.我认为这个问题的根本原因是为什么 C++ 决定禁止人们为自己的类型实现std::to_string() ,从而禁止我们在任何地方都遵循相同的接口。

For common things like hash or to_string() , isn't it better to have a single interface on language/ stdlib level and then expect users to conform to that interface, rather than having multiple interfaces?对于像hashto_string()这样的常见事情,在语言/标准stdlib级别上拥有一个接口然后期望用户遵守该接口而不是拥有多个接口不是更好吗?

why C++ decided to disallow people to implement std::to_string for their own type为什么 C++ 决定禁止人们为自己的类型实现std::to_string

This is where ADL is useful.这就是 ADL 有用的地方。 We already have the example of how to correctly do this with std::swap , which is successfully done in many codebases already:我们已经有了如何使用std::swap正确执行此操作的示例,这已经在许多代码库中成功完成:

template <typename T>
void swap_example(T & a, T & b) {
    using std::swap;
    swap(a, b);
}

This works if the namespace T is declared in has a compatible swap() function, without needing to overload std::swap .如果在其中声明的命名空间T具有兼容的swap() function,则此方法有效,而无需重载std::swap We can do the same thing with std::to_string :我们可以用std::to_string做同样的事情:

template <typename T>
void to_string_example(T const & x) {
    using std::to_string;
    to_string(x);
}

This will likewise work if the namespace T is declared in has a to_string function that can accept a T const & argument.如果命名空间T被声明为具有可以接受T const &参数的to_string function,这同样可以工作。 For example:例如:

namespace example {
    class Foo;

    std::string to_string(Foo const &);
}

to_string_example(example::Foo{}) would find and use the corresponding example::to_string function. to_string_example(example::Foo{})会找到并使用相应的example::to_string function。


remember where to use their version or the std version depends on the types they are dealing with... This sounds like a headache for me.记住在哪里使用他们的版本或标准版本取决于他们正在处理的类型......这对我来说听起来很头疼。

If this really is such a headache for you, you can hide the ADL behind a utility function in your project:如果这真的让您头疼,您可以在项目中将 ADL 隐藏在实用程序 function 后面:

template <typename T>
std::string adl_to_string(T const & x) {
    using std::to_string;
    return to_string(x);
}

Now you can use adl_to_string(...) instead of std::to_string(...) everywhere and not have to think about it.现在您可以在任何地方使用adl_to_string(...)而不是std::to_string(...)而不必考虑它。

This may sound a bit boring, but the purpose of std::to_string is to format as if you had used sprintf and as sprintf supports only a limited set of types this is also true for std::to_string .这可能听起来有点无聊,但std::to_string的目的是像您使用过sprintf一样进行格式化,因为sprintf仅支持有限的一组类型,这对于std::to_string也是如此。 There is no need to make it a template.无需将其设为模板。

As explained in detail in this answer that design does not have the restriction you think it has.如此答案中详细解释的那样,设计没有您认为的限制。 You can still supply your own foo::to_string(foo::bar&) and in code that uses proper qualification of the name to enable ADL your overload will be called.您仍然可以提供自己的foo::to_string(foo::bar&)并且在使用适当的名称限定来启用 ADL 的代码中将调用您的重载。 For this it is not necessary to add an overload to std .为此,没有必要向std添加重载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM