带升压变体的隔离错误

Segfault with boost variant

本文关键字:隔离 错误      更新时间:2023-10-16

我已经开始建立一点数据类型,在当前阶段,我在boost变体中只有一个递归类型。事实证明,当我尝试实例化我的类型时,我遇到了段错误。如果我在递归类型之前放一个字符串,它就可以工作,把它放在它不起作用的类型之后。我正在使用 gcc 4.8.1 64 位和 boost 1.54 的 mingw。

我使用提升变体的方式是否错误?

#include <boost/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <string>
#include <iostream>
struct A;
struct B;
using C = boost::variant<boost::recursive_wrapper<A>>;
// works:
// using C = boost::variant<std::string, boost::recursive_wrapper<A>>;
struct A {
  std::string name;
  C variant;
};
struct B {
  std::string name;
  C variant;
};
int main() {
  std::cout << "start" << std::endl;
  B hAST; // <--- segfaults
  std::cout << "end" << std::endl;
  return 0;
}
我相信

这是由于variant的"永不空"保证:C的默认构造函数必须使用其第一个模板参数的默认构造值(recursive_wrapper<A>)初始化自身,并且recursive_wrapper<A>的默认构造函数必须使用默认构造的A实例初始化自身,这会导致无限递归。

假设您实际上想要一个空的variantA的实例,您可以引入虚拟类型作为变体的第一个参数,例如:

struct variant_is_empty { };
using C = boost::variant<variant_is_empty, boost::recursive_wrapper<A>>;

编辑:看起来您可以将boost::recursive_wrapperboost::optional一起使用,这比在上述可选递归类型的情况下使用variant更容易。