如何确定boost :: variant变量是否为空?

Fer*_*nMG 10 c++ boost variant

我已经定义了一个boost :: variant var,如下所示:

boost::variant<boost::blank, bool, int> foo;
Run Code Online (Sandbox Code Playgroud)

该变量在实例化但未初始化时具有type值boost::blank,因为它boost::blank是传递给模板化boost :: variant的第一个类型.

在某些时候,我想知道是否foo已初始化.我试过这个,但效果不好:

if (foo) //doesn't compile
if (foo != boost::blank()) //doesn't compile
if (!(foo == boost::blank())) //doesn't compile
Run Code Online (Sandbox Code Playgroud)

我认为值得注意的是,当foo初始化(例如,foo = true)时,它可以通过执行来"重置" foo = boost::blank();.

如何检查是否foo已初始化,即它的类型不同boost::blank

seh*_*ehe 11

您可以定义访问者以检测"空白":

struct is_blank_f : boost::static_visitor<bool> {
   bool operator()(boost::blank) const { return true; }

   template<typename T>
   bool operator()(T const&) const { return false; }
};
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

bool is_blank(my_variant const& v) {
   return boost::apply_visitor(is_blank_f(), v);
}
Run Code Online (Sandbox Code Playgroud)

  • @FerranMG我的赌注:它不会增加开销.在启用优化的情况下进行编译. (6认同)
  • 看起来`0 == which()`检查无论如何都是胜利,从生成的程序集中猜测(clang 3.6和gcc 5.x).尝试基准测试,但很难在`which()`检查上得到有用的测量结果:https://github.com/rmartinho/nonius/issues/20 (2认同)

Lig*_*ica 7

当第一种类型是"活跃的"时,foo.which() == 0.用那个.

返回:从包含类型的有界类型集合中从零开始的索引*this.(例如,如果在variant<int, std::string>包含a 的对象上调用std::string,which()则会返回1.)

(http://www.boost.org/doc/libs/1_58_0/doc/html/boost/variant.html#idp288369344-bb)

  • 这可行,但如果`boost :: variant`定义中的类型的顺序发生变化,最终可能会成为问题的原因.它几乎总能完美地工作(更多是因为我试图确定变量是什么类型`boost :: blank`,这使得作为第一种类型更有意义),但我认为`boost ::如果它与`foo.which()== 0`一样便宜,那么<boost :: blank>(&foo)`将是一个更完整的解决方案.可悲的是,我想我将不得不在假设问题或实际开销之间做出选择,所以我可能最终会使用`which`. (3认同)
  • +1并同意.我仍然在答案中展示了访客的方法,因为这样的担忧往往源于恐惧.恐惧源于缺乏经验.游客不需要恐吓:) (2认同)