boost 变体对常用方法的简单调用

Posted

技术标签:

【中文标题】boost 变体对常用方法的简单调用【英文标题】:boost variant simple call to common methods 【发布时间】:2016-05-28 23:37:15 【问题描述】:

我有两个指针,只能设置其中一个,所以我正在考虑使用 boost::variant,比如:boost::variant<shared_ptr<Type1> shared_ptr<Type2>>。类型 1 和 2 不同,但它们共享一些功能。例如 Thay,两者都有方法 IsUnique

如果我有代码来检查初始化:

ASSERT(type1 != nullptr || type2 != nullptr);
ASSERT(type1 == nullptr || type2 == nullptr);
ASSERT(type1 == nullptr || type1->IsUnique());
ASSERT(type2 == nullptr || type2->IsUnique());

我希望能够用尽可能接近的东西替换它:

ASSERT(variant != nullptr);
ASSERT(variant->IsUnique());

但似乎我必须定义访问者,切换类型。

我是否遗漏了什么,是否有一个模板或什么可以让我将某些东西应用于当前类型的任何东西?可能是 c++14。

【问题讨论】:

听起来你可以使用多态性,存储一个指向基类的指针并在其中实现IsUnique @Dani 多态是一个选项,这就是我使用变体实现的目标 - OOP 多态不是唯一的选项,在我的情况下似乎有点偏离,因为对象具有非常不同的语义。我希望 C++ 有 golang 的能力来推断一个类型是否被实现而不创建类型之间的依赖关系。 【参考方案1】:

你可能会说

boost::apply_visitor([](auto const& obj)  obj.some_operation(); , v);

在最近提升的 c++14 中。让我试试看……

是的,您可以:Live On Coliru

#include <boost/variant.hpp>
struct A  void some_operation() const ; ;
struct B  void some_operation() const ; ;

using Obj = boost::variant<A, B>;

int main() 
    Obj v;
    boost::apply_visitor([](auto const& obj)  obj.some_operation(); , v);


我经常使用的一个模式是给访问者一个处理变体的重载:

 struct IsNullThing 
      bool operator()(Null) const  return true; 
      template <typename T> bool operator()(T) const  return false; 

      template <typename... Ts> bool operator()(boost::variant<Ts...> const& v) const 
          return boost::apply_visitor(*this, v);
      
 ;

这样你就可以做到:

 IsNullThing isNullThing;

 // and just call it

 MyVariant v;
 bool ok = isNullThing(v);

【讨论】:

这很酷,也适合我。没有我希望的那么短,但我可以按照你的建议准备一套助手。

以上是关于boost 变体对常用方法的简单调用的主要内容,如果未能解决你的问题,请参考以下文章

将boost变体的向量过滤成新的向量?

小窥KFold及其变体

boost::unordered_map 中以结构为键的 boost 变体

我初学VB 、 谁能将一些基本常用函数发给我?

常用优化方法总结

boost库常用库介绍