在 C++11 中,如何获取没有名称的临时左值?
Posted
技术标签:
【中文标题】在 C++11 中,如何获取没有名称的临时左值?【英文标题】:In C++11, how can I get a temporary lvalue without a name? 【发布时间】:2014-05-09 14:14:21 【问题描述】:我有一个传统的 C 库和一个函数 (setsockopts
) 需要一个指针参数。在 C++11 (gcc 4.8) 中,我可以在不初始化命名变量的情况下传递此参数吗?
我有以下不满意的解决方案:
#include <iostream>
#include <memory>
int deref(int const * p) return * p;
using namespace std;
int main()
int arg = 0; cout << deref(& arg) << endl;
// works, but is ugly (unnecessary identifier)
cout << deref(& 42) << endl;
// error: lvalue required as unary ‘&’ operand
cout << deref(& * unique_ptr<int>(new int(42))) << endl;
// works, but looks ugly and allocates on heap
【问题讨论】:
cout << deref(& (const int&) 42) << endl;
【参考方案1】:
如果这真的很麻烦,我会为setsockopt
创建一个包装器(未经测试)
template <typename T>
int setsockopt(int socket, int level, int optname, const T& value)
return setsockopt(socket, level, optname, &value, sizeof(value));
...
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, 1);
【讨论】:
“医生,我的头撞到墙上好痛!” “好吧,不要那样做!” +1【参考方案2】:编写一个函数模板将右值转换为左值:
template<typename T>
T &as_lvalue(T &&val)
return val;
现在,使用它:
deref(&as_lvalue(42));
警告:这不会延长临时对象的生命周期,因此您不能在创建临时对象的完整表达式结束后使用返回的引用。
【讨论】:
如another answer 中的示例,一个执行此操作的函数模板,另外还为您应用&
运算符,甚至可以窥视该运算符的任何用户覆盖,已经存在于标准库中...
@Cheersandhth.-Alf 除了绕过operator&
重载,我们不想那样做吗?
@Yakk:绕过operator&
的重载正是我想要做的。以及这个答案没有做什么。不了解你(复数)。【参考方案3】:
您可以将const
引用绑定到临时:
cout << deref(addressof<const int>(42)) << endl;
【讨论】:
嗯。这难道不是addressof
中的一个错误(即它可能应该确保它是用左值调用的)吗?
@Cheers:出于同样的原因&
不支持左值——很容易创建指向死对象的指针。
@Cheers “C++ 程序员必须一直处理有限的嵌套生命周期,没问题。” - “没问题”?我声称它是现代 C++ 中(如果不是)最大的错误来源之一。
我相信展示核心语言的方式来写这个deref(&(const int&)0);
会很有帮助。
我希望读者明白,到目前为止,Billy 所说的一切在技术上都没有意义,而且到目前为止,这不可能是由于任何误解。以上是关于在 C++11 中,如何获取没有名称的临时左值?的主要内容,如果未能解决你的问题,请参考以下文章