template<typename T>
struct X
{
X(T t) : t(std::forward<T>(t)) {}
T t;
};
template<typename T>
auto CreateX(T&& t) -> X<decltype(std::forward<T>(t))>
{
return X<decltype(std::forward<T>(t))>(std::forward<T>(t));
}
을 다음, 나는 X<const vector<int>&>
의 인스턴스를 생성하는 데 사용 및 X<vector<int>&&>
으로는 다음과
int main()
{
int vec = {1,2,3,4};
auto x1 = CreateX(vec);
auto x2 = CreateX(vector<int>{5,6,7,8});
cout << "x1: "; for(auto x : x1.t) cout << x << " "; cout << endl;
cout << "x2: "; for(auto x : x2.t) cout << x << " "; cout << endl;
}
출력은 :
x1: 1 2 3 4
x2: 0 0 33 0 0 0 7 8
은 임시 vector<int>{5,6,7,8}
의 수명이 연장되지 않고 rvalue- 참조 멤버 X::t
이 다른 것과 바인딩된다는 것을 보여줍니다.
좋아요,이 대답은 What is the lifetime of the class data member which const reference to a rvalue?에서 예상되는 동작입니다.
그러나 여기서 질문은 Expression templates and C++11의 Paul Preney의 코드에서 rvalue-references 멤버가 존재하는 한 임시 벡터가 존재할 수 있다는 점이 다릅니다. 임시 직원이 생기는 케이스 2를보십시오.
분명히이 여기에 사용 된 동일한 구조이지만, 아마도 뭔가 빠져 있습니다.
는는 편집 :
int main()
{
using namespace std;
auto expr = math_vector<3>{1.0, 1.1, 1.2} + math_vector<3>{2.0, 2.1, 2.2};
cout << "vec1: "; for(int i = 0; i < 3; ++i) cout << expr.le()[i] << " "; cout << endl;
cout << "vec2: "; for(int i = 0; i < 3; ++i) cout << expr.re()[i] << " "; cout << endl;
}
그리고이 출력하는 유효한 코드가 밝혀 : R. 마르틴 페르난데스의 답변에 따라 아래, 나는 다음을 시도
vec1: 1.0 1.1 1.2
vec2: 2.0 2.1 2.2
따라서 식 템플릿에 저장된 참조는 분명히 매달리지 않습니다. 여기서 무슨 일이 일어나고있는거야?
Nitpick : X의 생성자에서'std :: forward'은 단지'std :: move'를 말하는 장황한 방법 일뿐입니다. 'decltype (std :: forward (t))'도'T &&'를 말하는 매우 장황한 방법입니다. –