簡體   English   中英

包裝為完美的轉發構造函數

[英]Wrapper for perfect forwarding constructor

我想為B類的構造函數做一個包裝。

由於類B的某些部分是可替換的,因此我將這些部分的每種實現分組為幾個類A。

我使用完美轉發為構建B提供A的默認實現。

問題是包裝器不起作用。 如何解決這個問題?

謝謝。

以下也是https://godbolt.org/g/AWwtbf

template<typename T>
class A {
public:
    A() { _x = 2; }
    int _x;
};

template<typename T, typename C=A<T> >
class B {
public:
    explicit B(T x, C&& a = A<T>())
            : _x(x), _a(a) {
    }
    T _x;
    A<T>& _a;
};

template<typename T, typename C=A<T> >
B<T, A<T>> make_b(T x, C&& c = A<T>()) {
    return B<int, A<int>>(x, c);
};

int main() {
    B<int, A<int>> b1(1);  // this works.
    auto b2 = make_b(1);  // this doesn't
}

錯誤:

error: cannot bind rvalue reference of type 'A<int>&&' to lvalue of type 'A<int>'

     return B<int, A<int>>(x, c);

如何完美轉發東西?

  1. 將參數的類型設為template參數。
  2. 通過右值引用( && )接受參數。
  3. std::forward參數。

你得到了。 1和2,但忘記了nr。 3:

template<typename T, typename C=A<T> >
B<T, A<T>> make_b(T x, C&& c = A<T>()) {
    return B<T, A<int>>(x, std::forward<C>(c));
};

如何避免懸掛參考?

這段代碼創建了一個懸空的引用,即對已經消失的對象的引用:

    explicit B(T x, C&& a = A<T>())
            : _x(x), _a(a) {
    }
    T _x;
    A<T>& _a;

考慮一下這里發生的情況:創建了一個臨時A ,在左值表達式( a )中使用了右值引用a因此它變成了左值引用,隨后A& _a愉快地綁定到該值。 到全表達式完成時(在第一個; ),臨時A實例已被破壞,並且A& _a引用了不存在的對象。 如果在此之后使用_a ,則行為未定義。

在理解值類別對象生存期引用崩潰規則之前,請避免將引用作為數據成員。

只需按值存儲A

    explicit B(T x, C&& a = A<T>())
            : _x(x), _a(std::move(a)) {
    }
    T _x;
    A<T> _a;

或實例化A外的B並將其作為左值引用傳遞:

    explicit B(T x, C& a) : _x(x), _a(a) {}
    C& _a;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM