简体   繁体   English

为什么没有to_string(const string&)?

[英]Why is there no to_string(const string&)?

I have template code which needs to convert some template type to string.我有需要将某些模板类型转换为字符串的模板代码。 For this I overload to_string for my own types.为此,我为自己的类型重载了 to_string。 But the type can also be a string already.但是类型也可以已经是一个字符串。 Then compilation fails, because there is no overload of to_string for type string itself (just returning its argument).然后编译失败,因为类型 string 本身没有 to_string 的重载(只是返回它的参数)。

edit: example code:编辑:示例代码:

template<class T>
class TemplatedClass
{
public:

string toString() const
{
    // this should work for both simple types like int, double, ...
    // and for my own classes which have a to_string overload
    // and also for string, which is the reason for my question
    return string("TemplatedClass: ").append(to_string(t_));
}

private:
    T t_;
};

You can just write your own templated function with proper overloads as follows: 您可以使用适当的重载编写自己的模板化函数,如下所示:

#include <iostream>
#include <string>
using namespace std;

template<typename T>
std::string toString(const T& t) {
    return std::to_string(t);
}

std::string toString(const char* t) {
    return t;
}

std::string toString(const std::string& t) {
    return t;
}


int main() {
    cout << toString(10) << endl;
    cout << toString(1.5) << endl;
    cout << toString("char*") << endl;
    cout << toString(std::string("string")) << endl;
    return 0;
}

You can just combine all std::to_string and all your to_string by using derective. 您可以using derective将所有std::to_string和所有to_string组合在一起。 And pass std::string by value to minimize number of copies: std::string值传递std::string以最小化副本数:

#include <string>
#include <iostream>

namespace convert {
    std::string to_string(std::string s)
    {
        return s;
    }

    template<class T>
    std::string stringify(T&& t)
    {
        using convert::to_string;
        using std::to_string;
        return to_string(std::forward<T>(t));
    }
}

class Foo
{
public:
    operator std::string () const { return "Foo"; }
};

namespace bar {
    class Bar
    {};

    std::string to_string(const Bar&) {
        return "Bar";
    }
}

int main()
{
    std::string s{"I'm lvalue string"};
    std::cout << convert::stringify(42) << "\n";
    std::cout << convert::stringify(std::string("I'm string")) << "\n";
    std::cout << convert::stringify("I'm c-string") << "\n";
    std::cout << convert::stringify(s) << "\n";
    std::cout << convert::stringify(Foo{}) << "\n";
    std::cout << convert::stringify(bar::Bar{}) << "\n";

    return 0;
}

Note that with my approach you don't need an overload for const char * or any other type that is convertible to a string. 请注意,使用我的方法,您不需要为const char *或任何其他可转换为字符串的类型重载。 Also this approach allows a user to add to_string overload for any class (it will be found by argument-dependent lookup). 此方法还允许用户为任何类添加to_string重载(它将通过参数依赖查找找到)。

For further optimization convert::to_string accepting a string by value can be split into lvalue and rvalue overloads. 为了进一步优化,按convert::to_string value接受字符串的convert::to_string可以分为左值和右值重载。

Since C++17 you can use constexpr in if statements.从 C++17 开始,您可以在if语句中使用constexpr

You can use it as follows:您可以按如下方式使用它:

#include <iostream>
#include <string>

template<typename Ty>
std::string ToString(const Ty& value) {
    if constexpr (std::is_convertible_v<Ty, std::string>) {
        return value;
    }
    else {
        return std::to_string(value);
    }
}

int main() {
    std::cout << ToString(123) << std::endl;
    std::cout << ToString(123.0) << std::endl;
    std::cout << ToString("char*") << std::endl;
    std::cout << ToString(std::string("std::string")) << std::endl;

    return 0;
}

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

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