[英]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);
如何完美轉發東西?
template
參數。 &&
)接受參數。 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.