4

在如下函数中:

template<class Iterator>
A simple_return(Iterator it)
{
    return *it;
}

A a = simple_return(my_it); 

编译器可以轻松执行 RVO,因此请执行以下操作:

template<class Iterator>
A simple_return(Iterator it)
{
    A tmp = *it;
    return tmp;
}

但是,我已经看到第二种方式有时比前者更可取,例如在 STL 算法实现 (gcc) 中,我想知道这是否会以任何方式(如std::move(*it)std::move(tmp)确实)影响 RVO,或者有任何其他原因,因为例如,关于转换或其他任何事情。

例如reserver_iterator,,而不是:

reference operator*() const
{
     return *--Iterator(current);
}

用途:

reference operator*() const
{
     Iterator tmp = current;
     return *--tmp;
}

我之所以这么问,是因为为了实现类似 的重载operator+,我广泛使用了以下模式:

friend A operator+(const A& a, const A& b)
{ return A(a) += b; }

代替:

friend A operator+(const A& a, const A& b)
{
    A tmp(a);
    return tmp += b;
}

这并不是特别具有可读性,但使它长了 3 行(一行中的这两个句子会很丑)。

4

1 回答 1

1

由于命名返回值优化 (NRVO),两种变体都simple_return应该产生完全相同的机器代码。他们确实如此,即使有转换。因此,两者之间不应该有任何实际区别。

正如@cpplearner 所提到的,它是在您的STL 示例中完成的,因为前缀减量不能用于右值(例如,如果 Iterator 是指针)。其他部分可能会出现这种情况。

于 2017-04-23T11:59:07.673 回答