C++03中的Rvalues

4
你如何判断一个给定的参数是否为C++03中的rvalue?我正在编写一些非常通用的代码,需要尽可能地使用引用,或者在必要时构造一个新对象。我能否重载函数来接受按值传递和按引用传递,并使rvalue返回调用按值传递函数?
还是我有一种非常恶心的感觉,这就是为什么rvalue引用出现在C++0x中的原因?
编辑:
is_rvalue = !(is_reference || is_pointer) ?
5个回答

5
在C++03中,似乎有一种方法可以确定表达式是rvalue还是lvalue(我说“似乎”是因为我不确定自己是否理解这种技术)。需要注意的是,为了使该技术可用,几乎必须使用预处理器宏。Eric Niebler已经写了一篇关于如何使用BOOST_FOREACH的好文章,详细介绍了它的工作原理:

请注意,这篇文章很难懂(至少对我来说是这样),正如Neibler在其中所说:

毫无疑问,这是深奥的东西,但我们通过它获得了一种检测任何表达式的rvalue和lvalue特性的强大方法。

使用文章中描述的rvalue检测可能有助于您解决C++0x的rvalue引用解决的至少一些问题。


1
这是相关文章的页面。有趣的东西。 - academicRobot
@academicRobot:我简直不敢相信我竟然忘了链接到文章。现在已经加上链接了(正如你所说,rvalue检测的内容在第3页)。 - Michael Burr
+1,这是一个很棒的技巧,但它在运行时进行检查。我正在尝试扩展它,以便在编译时确定表达式是否为lvalue。我已经在这个问题上提出了询问。 - Aaron McDaid

2

在C++03中,如何判断给定的参数是否为rvalue?

你无法确定。你所能做的只是信任你的客户并欺骗:

void call_me_with_anything(const T& const_ref)
{
    /* read from const_ref */
}

void call_me_with_rvalue_only_please_i_trust_you(const T& const_ref)
{
    T& ref = const_cast<T&>(const_ref);
    /* write through ref */
}

我正在编写一些非常通用的代码

那么,如果您使用C++03可能不够用。


既然你要放弃const,那么它应该只适用于左值。如果它只适用于左值,那么你应该将参数设为非const引用。 - R Samuel Klatchko
你在说什么?这个可怕的转换的整个目的是修改 rvalues。 - fredoverflow

1

或许这就是为什么C++0x引入了右值引用?

你说得对,你需要C++0x和右值引用来实现这个。

我能想到的最接近的方法是使用const引用,因为它可以绑定到左值或右值(如果右值需要构造临时对象的话)。但是,你的代码将无法区分两者。


1
“或许我有一种非常令人作呕的感觉,这就是为什么rvalue引用被添加到C++0x中的原因?” “是的。这正是它们被添加到C++0x的原因。 在C++中,您无法创建重载以区分rvalue和lvalue。”

0

我正在编写一些非常通用的代码,如果可能的话需要参考,否则构造一个新对象。

这样做不就是你想要的吗?

void f(T& t);
void f(T const& t);

请注意...
T t; f(t); // calls f(T&)
f(T()); // calls f(T const&)

const T ct; f(ct); - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接