我怎样才能优化这个简单的功能?

Chr*_*s_F 1 c++ templates c++11

可以说我有以下内容:

template <class T>
std::string to_string(const T& item)
{
    std::ostringstream ss;
    ss << item;
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

是否有可能to_string在给定a的情况下创建一个重载,std::string只是转发参数而没有任何开销?

Pra*_*ian 6

我将添加一些重载,一个返回左值的副本,std::string另一个返回move右值std::string.

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

std::string to_string(std::string&& item)
{
    return std::move(item);
}

std::string s("Hello, World!");
std::cout << to_string(s) << std::endl;  // calls the lvalue overload

std::cout << to_string(std::string("Hello, World!")) << std::endl; // calls the rvalue overload
std::cout << to_string(20) << std::endl; // calls the function template
Run Code Online (Sandbox Code Playgroud)

现场演示


您也可以通过标记调度使用来完成数字std::to_string的工作.Tstd::to_stringstd::is_arithmetic<T>

template <class T>
std::string to_string_impl(const T& item, std::true_type)
{
    return std::to_string(item);
}

template <class T>
std::string to_string_impl(const T& item, std::false_type)
{
    std::ostringstream ss;
    ss << item;
    return ss.str();
}

template <class T>
std::string to_string(const T& item)
{
    return to_string_impl(item, std::is_arithmetic<T>{});
}
Run Code Online (Sandbox Code Playgroud)

现场演示


最后,如果你可以使用boost,你的功能可以替换为boost::lexical_cast.

auto str = boost::lexical_cast<std::string>(whatever);
Run Code Online (Sandbox Code Playgroud)


Mar*_*cia 5

是否有可能to_string在给出std::string... 的情况下创建一个重载...

当然.

std::string to_string(const std::string& str) {
   return str;
}
Run Code Online (Sandbox Code Playgroud)

......只是简单地转发论证而没有任何开销?

不确定你在这里的"前进"是什么意思,但......

您可以在提供临时或std::moved对象作为参数的情况下提供另一个重载to_string.使用r值参考.

std::string to_string(std::string&& str) {
   return std::move(str);
}
Run Code Online (Sandbox Code Playgroud)

注意,std::move返回语句在这里是必要的,因为如果没有使用它将导致副本(编译器将所有命名变量视为左值,并且使用str命名变量,则需要std::move).

现在你有两个版本重载,std::string第一个将有效地返回提供的参数的副本,而第二个版本利用临时对象和显式std::moved对象.

std::string str = "Hello World!";
auto str1 = to_string(str);    // *effectively* copies str to str1 [1]
auto str2 = to_string("Hi");   // *effectively* moves the temporary created here [1]
auto str3 = to_string(std::move(str));   // *effectively* moves str to str3; [1]
Run Code Online (Sandbox Code Playgroud)

[1]实际上,返回时可能还有一些额外的动作,编译器可能会在某些情况下应用复制省略优化.


UPDATE

不会auto str2 = to_string("Hi");调用模板函数,因为它不涉及隐式转换,因此更合适的重载?链接

你是对的.有了这个,你可以提供另一个接受a的重载const char*

std::string to_string(const char* str) {
   return str;
}
Run Code Online (Sandbox Code Playgroud)

或者你可以记录行为并让(更像是强迫)用户去做to_string(std::string("bah")).我很确定你会提供过载:-).