我有这样的功能:
void init_str(std::string _s)
{
std::string s{_s};
}
我希望通过允许const char*
重载来避免创建临时std::string
进行优化。
void init_str(const char* c)
{
std::string s{c};
}
但我也可以使用转发。
template<typename T>
void init_str(T&& t)
{
std::string s{std::forward<T>(t)};
}
但编译器对重载的偏好是:
const char*
std::string
那么我更喜欢哪种重载组合?
答案 0 :(得分:7)
假设c ++ 11或更高版本,性能最佳的解决方案是您尚未尝试过的解决方案:
void init_str(std::string s)
{
// just use s
}
因为复制省略将确保根本不构建任何不必要的临时。
使用std :: string(const char *)构造函数构造s(总共1个构造):
init_str("xxx");
使用复制构造函数构造s:
std::string x; // 1 constructor
init_str(x); // 1 copy constructor
使用移动构造函数构造s
std::string x; // 1 constuctor
init_str(std::move(x)); // 1 move constructor
实际上并没有创建临时文件:
std::string get_str() {
std::string s("xxx"); // 1 constructor, but...
return s; // ...because of RVO it's constructed at the call site
}
init_str(get_str()); // ... which is actually the constructor of s in init_str's arg list
// ... total constructors: 1
答案 1 :(得分:0)
首先考虑输入参数:
void init_str(std::string s)
{
// use s here ...
}
无论你怎么称呼函数,std::string
构造函数都应该做最有效的事情。
如果您使用临时呼叫,则会移动(std::move()
)。如果您使用const char*
进行呼叫,则会通过重载进行有效复制std::string()
构造函数。
因此,您无法真正提高创建参数字符串的效率。
如果您想要两个字符串或仅一个字符串,您的问题就不清楚了。如果你的函数需要两个字符串,那么:
void init_str(std::string s1)
{
std::string s2 = s1;
// use s1 & s2 here ...
}
鉴于您需要参数字符串的副本,移动不是一个选项。你不能只是让第二个字符串等于第一个字符串。 std::string
赋值运算符具有创建最有效副本所需的所有信息。
我不知道您的其他任何解决方案如何能够改善这一点。