首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在函数参数中区分rvalue和rvalue引用

如何在函数参数中区分rvalue和rvalue引用
EN

Stack Overflow用户
提问于 2016-03-17 01:29:47
回答 2查看 129关注 0票数 1

在传递参数时,我想在函数参数中区分这两种情况,如下所示:

代码语言:javascript
复制
int rvalue();
int&& rvalue_ref();

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

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

代码语言:javascript
复制
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"
}

它打印出这两种情况的“非参考资料”。在C++中有区分这两种情况的方法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-17 02:30:10

我不知道如何仅仅使用函数参数来完成这个任务。函数调用中可能会丢失xvalue和prvalue之间的区别。

但是,在调用函数之前,您可以使用一个对参数调用decltype的宏来完成这个任务。下面是一个用相关信息作为第二个参数调用函数的示例。我从this thread那里借用了代码。

代码语言:javascript
复制
#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);
}

输出:

代码语言:javascript
复制
prvalue
xvalue
lvalue

当然,您可以修改字符串以适应需要,也可以用枚举等替换字符串。

票数 3
EN

Stack Overflow用户

发布于 2016-03-17 02:47:05

您的代码之所以说“不是引用”,是因为您将T传递给了std::std::is_lvalue_reference<>std::std::is_rvalue_reference<>。您应该使用decltype()来获得它的原始类型。

代码语言:javascript
复制
template<class T>
void f( T&& x )
{
    if ( std::is_lvalue_reference< decltype( x ) >() )
    {
        std::cout << "Lvalue reference" << std::endl;
    }
    else if ( std::is_rvalue_reference < decltype( x ) >() )
    {
         std::cout << "Rvalue reference" << std::endl;
    }
    else
    {
        std::cout << "Not a reference" << std::endl;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36050087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档