将临时传递为LValues

时间:2010-07-08 15:58:13

标签: c++ swap assignment-operator lvalue

我想使用以下习语,我认为这是非标准的。我有使用返回值优化返回向量的函数:

vector<T> some_func()
{
    ...
    return vector<T>( /* something */ );
}

然后,我想用

vector<T>& some_reference;
std::swap(some_reference, some_func());

some_func不返回LValue。上面的代码是有道理的,我发现这个成语非常有用。但是,这是非标准的。 VC8仅在最高警告级别发出警告,但我怀疑其他编译器可能会拒绝它。

我的问题是:是否有某种方法可以实现我想要做的同样的事情(即构造一个向量,分配给另一个,并销毁旧的),这是合规的(和不使用赋值运算符,见下文)?

对于我编写的类,我通常将赋值实现为

class T
{
    T(T const&);
    void swap(T&);
    T& operator=(T x) { this->swap(x); return *this; }
};

利用了复制省略,解决了我的问题。但是对于标准类型,我真的想使用swap,因为我不想要临时的无用副本。

由于我必须使用VC8并生成标准C ++,我不想听到C ++ 0x及其右值引用。

编辑:最后,我提出了

typedef <typename T>
void assign(T &x, T y)
{
    std::swap(x, y);
}

当我使用左值时,因为如果y是临时的,编译器可以自由地优化对复制构造函数的调用,并且当我有左值时,可以使用std::swap。我使用的所有类都是“必需的”来实现std::swap的非愚蠢版本。

3 个答案:

答案 0 :(得分:1)

如果您不想要无用的临时副本,请不要按值返回。 使用(共享)指针,通过引用传递函数参数来填充,插入迭代器,....

您是否有特定原因想要按值返回?

答案 1 :(得分:1)

由于std::vector是类类型,因此可以在rvalues上调用成员函数:

some_func().swap(some_reference);

答案 2 :(得分:0)

我知道的唯一方法 - 在标准的限制范围内 - 实现你想要的是应用表达式模板元编程技术:http://en.wikipedia.org/wiki/Expression_templates这对你来说可能很容易情况下。