为什么我的结构不能有 boost::variant 类型的成员,但可以有 vector<boost::variant> 类型的成员?

Why can my struct not have a member of type boost::variant but can have a member of type vector<boost::variant>?

我定义了以下 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;
};

但是,上面写的结构 不会 编译,给出错误页面(太多不能包含在这里),主要与 "incomplete type not allowed."[=18 有关=]

第一个编译器错误是:

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 中,而不是在其他情况下。

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

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

你需要打破依赖循环。


意外解决方案

当你使用 std::vector<BaseNodeType> 而不是 BaseNodeType 和你的特定库实现 意外 workaround/solution

=50=]支持这个。

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

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

Surefire 解决方案

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;
}