存储完美的前向价值

时间:2018-05-06 02:25:31

标签: c++

在此代码中制作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;
}

2 个答案:

答案 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&&