我定义了以下 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;
};
但是,上面编写的结构将不会编译,给出错误页面(这里包含的内容太多),主要与&#34;不允许的不完整类型有关。&#34;
第一个编译器错误是:
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
内部而不是其他情况下编译器能够解析这些类型。
答案 0 :(得分:4)
使用类型作为成员要求它是完整的(显然,因为需要知道大小)。
因此有catch-22(变体的大小现在取决于SharedNodeType的大小,反之亦然)。
你需要破坏依赖循环。
当您使用std::vector<BaseNodeType>
intead BaseNodeType
时,您遇到了意外变通办法/解决方案,并且您的特定库实现慷慨/不小心支持此功能。
据我所知,这从来就不是标准库容器的必需功能,实际上我想我记得在实例化时,规范而非强制 value_type是完整的。< / p>
现在,您仍然可以通过切换到Boost Container的vector
模板(boost::containers::vector<BaseNodeType>
)来可靠地使用此变通方法,显式支持不完整类型的实例化
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;
}