【问题标题】:map with incomplete value type具有不完整值类型的映射
【发布时间】:2012-08-30 03:55:05
【问题描述】:

我收到以下错误:

class Test
{
    std::map<std::string,Test> test;
};

错误是“字段的类型'Test'不完整”。我读了一些帖子,建议这可能是 xcode 附带的 libcxx 版本中的一个错误,但如果我只需将其更改为:

class Test
{
    std::map<std::string,std::shared_ptr<Test>> test;
};

我只是想再次确认这绝对是一个正确的错误,而不是一个错误。

干杯!

【问题讨论】:

  • 为我工作,gcc 4.6.3 @ ubuntu x64
  • 标准要求标准容器中使用的所有类型都是完整的,所以报错是有效的。但是,该库的一些实现也可以处理不完整的类型。
  • std::map&lt;std::string,std::shared_ptr&lt;Test&gt;&gt;std::map&lt;std::string,Test&gt; 在语义上非常不同!第一个存储(智能)指针,而第二个存储“整个”对象。
  • @avakar 解释了为什么代码在 VS 2012 下编译而不是 XCode..
  • @Joe : Boost.Variant 附带boost::recursive_wrapper&lt;&gt;正好解决这个问题。 :-]

标签: c++ map c++11 std libc++


【解决方案1】:

标准要求,标准库的模板组件中使用的所有类型必须是完整的,除非另有说明。因此 libc++ 的错误是正确的。使用不完整的类型是未定义的行为(§17.6.4.8[res.on.functions]/2),所以 libstdc++ 接受它也没有错。

您可以像以前一样使用指针对象来构造完整的类型。但是您也可以使用一些允许不完整类型的第三方集合库,例如boost::container::mapdesigned to allow incomplete types


§17.6.4.8 其他功能/2:

特别是在以下情况下效果是不确定的:

  • ...

  • 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非该组件特别允许。

(明确允许不完整类型的唯一组件是 declvalunique_ptrdefault_deleteshared_ptrweak_ptrenable_shared_from_this。)

【讨论】:

  • 注意 N4510(2015 年 5 月采用)需要 std::vectorstd::liststd::forward_list 以支持不完整的值类型。为避免破坏 ABI,提案中并未包含所有容器。在未来的 C++ 版本中(可能在 C++17 之后),对关联容器很可能会有类似的要求。
猜你喜欢
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2023-03-07
  • 2015-06-27
  • 2012-05-12
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多