【问题标题】:Why can my struct not have a member of type boost::variant but can have a member of type vector<boost::variant>?为什么我的结构不能有 boost::variant 类型的成员,但可以有 vector<boost::variant> 类型的成员?
【发布时间】:2016-02-11 18:17:37
【问题描述】:

我已经定义了以下 boost::variant 类型:

#include <boost/variant.hpp>
#include <vector>
#include <string> 

struct SharedNodeType;
typedef float TypeA;
typedef int TypeB;
typedef std::string TypeC;
typedef char* TypeD;

typedef boost::variant
<TypeA, TypeB, TypeC, TypeD, SharedNodeType> BaseNodeType;

其中 TypeA、TypeB、TypeC 和 TypeD 是完全限定的完整类型(确切的类型无关紧要,但在这种情况下它们是其他结构)。

我已经定义了以下结构:

struct SharedNodeType
{
     std::string nodeName;
     BaseNodeType node;
};

然而,上面写的结构不会编译,给出错误页面(这里包括太多),主要与“不允许的不完整类型”有关。

第一个编译器错误是:

In file included from ./apps/iv_parserTest.cc(1):
/opt/common/boost/1.50.py2.7/include/boost/mpl/sizeof.hpp(27): error: incomplete type is not allowed
 : mpl::size_t< sizeof(T)>

但是,如果我将结构更改为以下,它编译没有问题:

struct SharedNodeType {
     std::string nodeName;
     std::vector<BaseNodeType> node;
};

由于我的SharedNodeType 永远不会有多个节点,这对我来说似乎很浪费。

为什么结构的第二种形式会编译,而第一种形式不会?

编辑: 在进行了更多试验后,我确定问题似乎在于 BaseNodeType 变体类型也包含 SharedNodeType。我已经相应地更新了我的代码示例,但它仍然留下了一个问题,即为什么编译器能够解析类型,如果它们在 std::vector 内而不是其他类型。

【问题讨论】:

  • 当你做BaseNodeType node;时知道TypeA, TypeB, TypeC, TypeD吗?
  • 引发的实际编译器错误是什么?
  • @NathanOliver 是的。所有这些类型都是完整的。我已经更新了代码和问题以使其更清晰。
  • This 可能是相关的。

标签: c++ boost boost-variant incomplete-type


【解决方案1】:

使用类型作为成员要求它是完整的(显然,因为需要知道大小)。

因此有 catch-22(变体的大小现在取决于 SharedNodeType 的大小,反之亦然)。

你需要解开依赖循环。


意外解决办法

当您使用 std::vector&lt;BaseNodeType&gt; 而不是 BaseNodeType 时,您遇到了一个意外解决方法/解决方案,并且您的特定库实现优雅/意外地支持了这一点。

据我所知,这从来都不是标准库容器所必需的功能,事实上我想我记得规范而不是要求 value_type 在实例化时是完整的。

现在,您仍然可以通过切换到 Boost Container 的 vector 模板 (boost::containers::vector&lt;BaseNodeType&gt;) 可靠地使用此解决方法,该模板明确支持不完整类型的实例化。

万无一失的解决方案

Boost Variant 有自己的工具来处理不完整的类型,专门用于创建(潜在的)递归变体类型。

您的原始样本看起来像这样,已修复:

Live On Coliru

#include <boost/variant.hpp>
#include <vector>
#include <string> 

struct SharedNodeType;
typedef float       TypeA;
typedef int         TypeB;
typedef std::string TypeC;
typedef char*       TypeD;

typedef boost::variant<TypeA, TypeB, TypeC, TypeD, boost::recursive_wrapper<SharedNodeType> > BaseNodeType;

struct SharedNodeType
{
     std::string nodeName;
     BaseNodeType node;
};

int main() {
    BaseNodeType bnt;
    SharedNodeType snt;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多