在此代码中制作a和b的副本是否不可避免?我认为保持参考是不可能的,因为一些传递的值可能是一个右值。只是检查什么替代我可以使用..
template<typename S, typename T>
static bool TEST_EQ(S&& expected, T&& received, std::string const & error_msg)
{
auto a = forward<S>(expected);
auto b = forward<T>(received);
bool test = a == b;
if(!test)
{
std::cout << "Failed: expected:" << a << " received:" << b << std::endl;
std::cout << error_msg << std::endl;
}
return test;
}
我可以确认下面的版本是免费的,对吧?如果rvalue传递给函数,我相信只有参数tmp变量存在,对吗?
template<typename S, typename T>
static bool TEST_EQ(S&& expected, T&& received, std::string const & error_msg)
{
bool test = expected == received;
if(!test)
{
std::cout << "Failed: expected:" << expected << " received:" << received << std::endl;
std::cout << error_msg << std::endl;
}
return test;
}
答案 0 :(得分:2)
如果您正在做一些可以利用rvalues的事情,例如移动分配给变量,通常只需要使用std::forward
。在这里,您首先不需要作业。
template<typename S, typename T>
static bool TEST_EQ(S&& expected, T&& received, std::string const & error_msg)
{
bool test = expected == received;
if(!test)
{
std::cout << "Failed: expected:" << expected << " received:" << received << std::endl;
std::cout << error_msg << std::endl;
}
return test;
}
答案 1 :(得分:1)
在原始案例中:
auto a = forward<S>(expected);
auto b = forward<T>(received);
auto
不会被推断为参考类型,所以
如果传入左值,则会调用复制构造函数。
如果传入一个右值,将调用移动构造函数(如果有一个定义的那个)。
为避免复制或移动,您可以使用auto&amp;&amp ;;(如评论中Daniel H所述):
auto&& a = forward<S>(expected);
auto&& b = forward<T>(received);
如果你传入左值,a, b
将是S&, T&
- 没有复制构造函数调用
如果你传入左值,a, b
将是S&&, T&&
- 没有移动构造函数调用
我可以确认下面的版本是免费的,对吧?如果一个右值是 传递给函数,我相信只有参数tmp变量 存在,对吧?
是的,因为你没有在函数中声明任何变量。通用引用中的参数类型总是推断为引用类型(例如S&
或S&&
)