下面一段代碼元組的右值參考
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
class A {
int m_a;
public:
A(): m_a(10) { std::cout << "Default Constructor " << m_a << ", this: " << this << std::endl; }
A(int a): m_a(a) { std::cout << "Main Constructor " << m_a << ", this: " << this << std::endl; }
A(const A& a): m_a(a.m_a) { std::cout << "Copy Constructor: " << m_a << ", this: " << this << std::endl; }
A(const A&& a): m_a(std::move(a.m_a)) { std::cout << "RValue copy Constructor " << m_a << ", this: " << this << std::endl; }
int get() const { return m_a; }
virtual ~A() { std::cout << "Destructor " << m_a << ", this: " << this << std::endl; }
};
int main() {
{
typedef std::tuple< A&& > MyContainer;
std::vector<MyContainer> myVec;
{
A a(100);
A b(200);
myVec.push_back(std::make_tuple(a));
myVec.push_back(std::make_tuple(b));
std::cout << "Innermost scope" << std::endl;
}
std::cout << "Intermediate scope" << std::endl;
auto& x = get<0>(myVec.at(0));
auto& y = get<0>(myVec.at(1));
std::cout << x.get() << std::endl;
std::cout << y.get() << std::endl;
}
std::cout << "Outermost scope" << std::endl;
return 0;
}
我想到的是,在離開intermeidate範圍,載體自毀並且它試圖破壞元組中conatain。這反過來破壞了A的對象,但是一些我沒有看到任何對象被破壞。 Valgrind也不會顯示任何內存錯誤。以下爲輸出時的valgrind $的valgrind ./a.out
==7366== Memcheck, a memory error detector
==7366== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7366== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7366== Command: ./a.out
==7366==
Main Constructor 100, this: 0x7fefffc70
Main Constructor 200, this: 0x7fefffc60
Copy Constructor: 100, this: 0x7fefffcb0
Destructor 100, this: 0x7fefffcb0
Copy Constructor: 200, this: 0x7fefffcd0
Destructor 200, this: 0x7fefffcd0
Innermost scope
Destructor 200, this: 0x7fefffc60
Destructor 100, this: 0x7fefffc70
Intermediate scope
100
200
Outermost scope
==7366==
==7366== HEAP SUMMARY:
==7366== in use at exit: 0 bytes in 0 blocks
==7366== total heap usage: 2 allocs, 2 frees, 24 bytes allocated
==7366==
==7366== All heap blocks were freed -- no leaks are possible
==7366==
==7366== For counts of detected and suppressed errors, rerun with: -v
==7366== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
跑我這裏顯然缺少一些東西。如果在中間範圍中對「get()」的調用確實返回了適當的值(100和200),爲什麼當矢量(和元組)被破壞時調用「A」的析構函數?
@編輯] @霍華德Hinnant:謝謝,它是非常有意義的。我不明白的是: 1)當我用一個右值構造一個元組並將它推送到矢量時,我確實得到了valgrind內存錯誤。例如。
myVec.push_back(std::make_tuple(10));
在最內側範圍並添加
:
auto& z = get<0>(myVec.at(2));
std::cout << z.get() << std::endl;
在上述實施例的中間範圍的valgrind產生的存儲器錯誤,但是上面未示出的左值的引用。
2)有人可以解釋爲什麼下面的語句調用copu構造函數和立即desctructor?
myVec.push_back(std::make_tuple(a));
感謝您的回答,它非常有意義。我在上面添加了更多的後續問題,你能否看看你是否可以回答他們? – Aravind