gpt4 book ai didi

c++ - 为什么转发引用不是常量?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:26 24 4
gpt4 key购买 nike

转发引用应该将参数转发给另一个函数,对吧?那为什么它不是 const 呢?

template <typename T>
void func(const T&&);

非常量引用允许函数修改其参数(而不是仅仅转发它们)。

最佳答案

Why isn't forwarding reference const?

因为希望能够移动一个完美转发的 xvalue。通常不能从 const 引用移动对象,因为移动构造函数的参数需要是非常量。

此外,希望能够将左值绑定(bind)到转发引用中。不可能将左值绑定(bind)到 const T&& 中,这是一个 const 右值引用 - 它根本不是转发引用 1

如果您不想离开论点,而只是不断地引用它,那么您不需要转发引用。在这种情况下,const 左值引用就足够了。

例子:

struct S {
S() = default;
S(S&&) = default; // move
S(const S&) = default; // copy
};

void foo(S fooarg);

template <typename T>
void bar(T&& bararg) { // forwarding reference
foo(std::forward<T>(bararg));
}

// call site
S s;
bar(s); // 1 copy
bar(S{}); // 2 move
bar(std::move(s)); // 3 move

这里我们希望在情况 2 和情况 3 中将 bararg 移动到 fooarg 中,并且我们希望在情况 1 中复制它。转发引用实现了这一点。 const 右值引用不会,因为不可能将 const 引用传递给移动构造函数。


Const 右值引用很少有用。标准库在 few places 中使用它们:

template <class T> void as_const(const T&&) = delete;
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;

这些删除的重载的目的是防止使用临时参数(右值)调用函数。 const 防止参数成为转发引用,它会绑定(bind)到任何东西并因此删除任何调用。

constexpr const T&& optional::operator*() const&&;
constexpr const T&& optional::value() const &&;

template <class T, class... Types>
constexpr const T&& get(const std::variant<Types...>&& v);

template< class T, class... Types >
constexpr const T&& get(const tuple<Types...>&& t) noexcept;

上面,当访问包装值时,const 右值引用用作包装器的返回类型,因此保持包装值的值类别和常量性。


1 标准(草案)说:

[temp.deduct.call] ... A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template (during class template argument deduction ([over.match.class.deduct])). If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.

关于c++ - 为什么转发引用不是常量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56694942/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com