2015-05-27 38 views
2

我想在std :: vector中存儲三個任意int,而不定義結構/類。所以我去的std ::元組<>:std :: std :: tuples的向量導致未知的大小

std::vector<std::tuple<unsigned int, unsigned int, unsigned int> 

使用MS VS 2013,它會導致以下錯誤:

>c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(1628): error C2036: 'std::tuple<unsigned int,unsigned int,unsigned int> *' : unknown size 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(1622) : while compiling class template member function 'void std::vector<std::tuple<unsigned int,unsigned int,unsigned int>,std::allocator<_Ty>>::_Tidy(void)' 
1>   with 
1>   [ 
1>    _Ty=std::tuple<unsigned int,unsigned int,unsigned int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(945) : see reference to function template instantiation 'void std::vector<std::tuple<unsigned int,unsigned int,unsigned int>,std::allocator<_Ty>>::_Tidy(void)' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::tuple<unsigned int,unsigned int,unsigned int> 
1>   ] 
1>   d:\projects\gl33\src\nvf.cpp(39) : see reference to class template instantiation 'std::vector<std::tuple<unsigned int,unsigned int,unsigned int>,std::allocator<_Ty>>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::tuple<unsigned int,unsigned int,unsigned int> 
1>   ] 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ======= 

這是由於MSVS2013編譯器限制?或者我做錯了什麼?

+4

我想你忘了包含''標題:'#include ' - 當只包含''而不是''時,我可以重現你的錯誤信息。 – dyp

+1

該死的,你說得對。只是認爲它已經包括在內。感謝您的評論。你會重新發布爲答案,我可以標記爲已解決? – madmartin

回答

2

一個類的類型是已知的(它的名字是已知的),但它的大小是未知的,如果該類型只是前向聲明,但沒有定義。例如。

struct X; 

sizeof(X) // error: X is incomplete 

一個類型的大小爲指針運算,看着編譯器錯誤(其中提到的指針tuple)時,這是另一個重要的暗示。

MSDN提供following example for C2036

struct A* pA; 
int main() { 
    pA++; // C2036, size of A not known 
    ((char*&)pA)++; // OK, if sizeof(A) == sizeof(char) 
} 

struct A* pa隱含向前聲明struct A


這種情況可以用標準庫的頭髮生時不包括所有必需自己頭。標準庫中的類型之間有相互依賴關係。如果標準庫標題僅需要前向聲明tuple,則它不會包含重量級標頭本身,以減少編譯時間。

我可以通過僅包含<vector>而不是<tuple>來重現OP中的問題。解決方案:使用vector<tuple<..>>包括<tuple>(以及<vector>)手動包含所有需要類型的標頭。一般來說,包含一個頭文件可以保證一定類型的可用性。爲了最大限度地提高可移植性,請務必確保您所包含的頭文件保證您可以使用程序中的所有類型(*)

(*)更具體地說,您應該確保您有程序需要定義的所有類型的定義。標準庫容器要求它們的值類型是完整的(至少在類模板實例化的地方)。因此,如果您的程序需要定義vector<tuple<unsigned, unsigned>>,則還需要定義tuple<unsigned, unsigned>

+0

感謝您對該主題的闡述! – madmartin