【问题标题】:std::vector of std::tuples leads to unknown sizestd::tuples 的 std::vector 导致未知大小
【发布时间】:2015-05-27 16:12:17
【问题描述】:

我想在 std::vector 中存储三个任意整数而不定义结构/类。所以我选择了 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 编译器的限制吗?还是我做错了什么?

【问题讨论】:

  • 我猜你忘了包含 &lt;tuple&gt; 标头:#include &lt;tuple&gt; - 当只包含 &lt;vector&gt; 而不是 &lt;tuple&gt; 时,我可以重现您的错误消息。
  • 该死,你是对的。只是以为已经被收录了。感谢您的评论。你会重新发布一个我可以标记为已解决的答案吗?

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


【解决方案1】:

一个类的类型是已知的(它的名字是已知的),但是如果该类型只是被前向声明但没有被定义,那么它的大小是未知的。例如

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 标头本身以减少编译时间。

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

(*) 更具体地说,您应该确保您的程序需要定义的所有类型都有定义。标准库容器要求它们的值类型是完整的(至少在类模板被实例化的地方)。因此,如果您的程序需要vector&lt;tuple&lt;unsigned, unsigned&gt;&gt; 的定义,它也需要tuple&lt;unsigned, unsigned&gt; 的定义。

【讨论】:

  • 感谢您对该主题的详细阐述!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 2010-09-20
  • 2017-12-18
  • 2015-05-19
  • 1970-01-01
相关资源
最近更新 更多