std :: std :: tuples的矢量导致未知大小

时间:2015-05-27 16:12:18

标签: c++11 vector visual-studio-2013 tuples

我想在std :: vector中存储三个任意int而不定义struct / class。所以我去了std :: tuple<>:

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编译器的限制吗?或者我做错了什么?

1 个答案:

答案 0 :(得分:4)

类类型是已知的(它的名称是已知的)但如果类型只是前向声明但未定义,则其大小是未知的。 E.g。

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的前向声明,则它不会包含重量级tuple标头本身,以减少编译时间。

我可以通过仅包含<vector>而不是<tuple>来重现OP中的问题。解决方案:手动包含您需要的所有标题类型 - 使用vector<tuple<..>>时,包括<tuple>(以及<vector>)。通常,包括标题可确保某些类型的可用性。为了最大限度地提高可移植性,请始终确保您所包含的标题保证您可以使用程序中的所有类型(*)

(*)更具体地说,您应该确保您的程序需要定义的所有类型的定义。标准库容器需要完成它们的值类型(至少在实例化类模板的时候)。因此,如果您的计划需要vector<tuple<unsigned, unsigned>>的定义,则还需要tuple<unsigned, unsigned>的定义。