const引用是不良的C 11

const reference is bad C++ 11

本文关键字:不良 引用 const      更新时间:2023-10-16

我在YouTube上观看Bjarne Stroustrup,我试图弄清楚为什么这被认为是不好的,因为他说这是C 98样式不良代码

void setInt(const unsigned int &i)
void takeaString(const std::string &str)

我的意思是您正在传达对常数的引用,以便您保存自己的复制操作,甚至不像传递指针一样使用它,所以它不必退出,所以为什么不好?

在pre-c 11中,一般经验法则是如果不修改参数,请按值传递内置类型和一个对象const& 的类或结构,因为类或结构的对象通常如此之大,以至于通过const&付费在绩效方面付费。

现在,这是一个相当任意的规则,当然,您还将看到例外(例如,标准库中的迭代器),但它在实践中效果很好,并且是一个已建立的习语。当您在其他一些程序员的代码中看到f(int const &i)f(std::string s)时,您会想知道原因,如果没有明显的原因,人们会感到困惑。

在C 11中,故事可能不同。许多人声称,由于新的语言特征(移动语义和RVALUE参考),按值传递大对象不再是性能问题,甚至可能更快。看这篇文章:"想要速度?按价值传递。"但是,当您查看过去的堆栈溢出讨论时,您还会发现有经验丰富的程序员反对这种观点。

就个人而言,我没有下定决心。我认为C 11太新了,无法真正判断什么是好与坏。

尽管如此,如果您出于任何原因必须使用Pre-C 11编译器,则C 11通常是无关紧要的,因此在任何情况下都必须了解Pre-C 11规则。

这是好的:

bool session_exists(heavy_key_t const& key)
{
    // why would we ever want to copy the key if we don't need to
    return sessions.find(key)) == sessions.end();
}

这是当通过参考传递参数可能不是很好的时候:

struct session {
    heavy_key_t key_;
    session(heavy_key_t const& key):
        key_(key) // <-- we are taking a copy anyway, why not letting compiler do it
    {}
};

,另一个在值中可以很好地效果,这要归功于复制ELISION优化和RVO:

template <class T, class Merger>
T merge(T state, T update, Merger const& merger) {
    // merger is still by reference, we don't need the copy of it
    return merger(std::move(state), std::move(update));
}