☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

合理使用 std::forward

10.6.14 ID_unsuitableForward
目录 › next › previous

std::forward 的参数应为“转发引用(forwarding references)”,返回值应直接作为接口的参数,除此之外的使用方式价值有限,且易产生错误。

转发引用是类型为 T&& 的参数,T 为函数模板类型,左值和右值均可与之绑定,可参见 ID_illForwardingReference 的进一步说明。

示例:

struct A { .... };

void foo(A&);        // #1
void foo(const A&);  // #2
void foo(A&&);       // #3

template <class T>
void bar(T&& x) {        // Forwarding reference
    foo(forward<T>(x));  // Compliant
}

void baz(const A& a) {
    A b(a);
    bar(b);    // Calls #1
    bar(a);    // Calls #2
    bar(A());  // Calls #3
}

例中 bar 接口的参数为转发引用,在 baz 函数中,bar 接口将左值、常量引用和临时对象分别转发给对应的 foo 接口,这种模式称为“完美转发”,std::forward 应在这种模式内使用。

下面给出几种错误示例:

void bar(A&& x) {
    foo(forward<A>(x));  // Non-compliant, ‘x’ is not a forwarding reference
}

template <class T>
struct X {
    void bar(T&& x) {
        foo(forward<T>(x));  // Non-compliant, ‘x’ is not a forwarding reference
    }
};

注意,转发引用的类型只能是函数模板类型,非模板和类模板不构成转发引用。

template <class T>
void bar(T&& x) {
    T y = forward<T>(x);  // Non-compliant, ‘y’ is always an lvalue
    foo(y);
}

template <class T>
void bar(T&& x) {
    foo(forward<T&>(x));  // Non-compliant, use ‘forward<T>(x)’
}

例中 forward 的返回值应直接作为接口的参数,且只应使用 forward<T>。

相关

ID_illForwardingReference

依据

ISO/IEC 14882:2011 20.2.3(1) ISO/IEC 14882:2017 23.2.5(1)

参考

C++ Core Guidelines F.19
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.