c++ - 如何区分函数参数中的左值和右值引用

标签 c++ c++11

当传递一个参数时,我想在一个函数参数中区分这两种情况,像这样:

int rvalue();
int&& rvalue_ref();

f(rvalue());
f(rvalue_ref());

但是,当我尝试像这样转发引用时:

int rvalue()
{
    return 1;
}

int&& rvalue_ref(int i)
{
    return std::move(i);
}

template<class T>
void f(T&& x)
{
    if (std::is_rvalue_reference<T>())
    {
        std::cout << "Rvalue reference" << std::endl;
    }
    else if (std::is_lvalue_reference<T>())
    {
        std::cout << "Lvalue reference" << std::endl;
    }
    else
    {
        std::cout << "Not a reference" << std::endl;
    }
}

int main() 
{
    f(rvalue()); // Should print "Not a reference"
    f(rvalue_ref(1)); // Should print "Rvalue reference"
}

对于这两种情况,它都打印出“Not a reference”。有没有办法在 C++ 中区分这两种情况?

最佳答案

我不知道如何仅使用函数参数来做到这一点。在函数调用中可能会丢失 xvalue 和 prvalue 之间的区别。

但是您可以在调用函数之前使用在参数上调用 decltype 的宏来实现。这是一个使用相关信息作为第二个参数调用您的函数的示例。我从this thread借了代码.

#include <iostream>

int rvalue()
{
    return 1;
}

int&& rvalue_ref(int &&i)   // Modified signature to avoid return reference to local variable (ty. user657267)
{
    return std::move(i);
}

template<typename T>
struct value_category {
    // Or can be an integral or enum value
    static constexpr auto value = "prvalue";
};

template<typename T>
struct value_category<T&> {
    static constexpr auto value = "lvalue";
};

template<typename T>
struct value_category<T&&> {
    static constexpr auto value = "xvalue";
};

// Double parens for ensuring we inspect an expression,
// not an entity
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value

#define f(X) f_(X, VALUE_CATEGORY(X)) 

template<class T>
void f_(T&& x, char const *s)
{
    std::cout << s << '\n';
}

int main() 
{
    f(rvalue()); // Should print "Not a reference"
    f(rvalue_ref(1)); // Should print "Rvalue reference"
    int j; f(j);
}

输出:

prvalue
xvalue
lvalue

当然你可以简单地修改字符串以适应,或者用枚举替换它们等。

关于c++ - 如何区分函数参数中的左值和右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36050087/

相关文章:

c++ - 为什么 std::shared_ptr 的别名构造函数不初始化 std::enabled_shared_from_this?

c++ - 从 STL 迭代器非公开派生的自定义迭代器的最小功能?

c++ - 由于 Linux C++ PowerPC 上的 SIGABRT 导致崩溃

c++ - 在每次循环迭代时一起添加可变数量的数组元素

c++ - "two-graph"中更改次数有限的最短路径

c++ - 如何使用 Visual Studio 2010 在 Windows 上使用 Open MPI 构建 boost::mpi 库

c++ - 如何使用 C++11 的最小 gc 支持

数组的 C++ 构造函数初始值设定项

c++ - 构造函数初始化列表中可变参数的 Lambda 捕获

c++停止在ctrl-d上要求输入