如何实现 boost::variant 派生类?

2024-02-11

我已经尝试了几个小时来编写一个派生类boost::variant。但我不明白问题是什么(我不明白编译错误意味着什么)。

实施清洁的规则是什么boost::variant派生类?

#include <boost/variant.hpp>

class MyVariant : public boost::variant<char,bool>
{
public:    
       MyVariant ()          : boost::variant<char,bool>( ) {}

       template <typename T>
       MyVariant(      T& v) : boost::variant<char,bool>(v) {}

       template <typename T>
       MyVariant(const T& v) : boost::variant<char,bool>(v) {}
};

int main ()
{
      MyVariant a;
      MyVariant b = a;        //compilation error
  //  MyVariant c = MyVariant();
  //  MyVariant d (true);
  //  MyVariant e ('E');
}

为什么我要使用继承?(编辑以向@zaufi提供更多详细信息)

  • 我想要一个空的状态
  • 我想接受const char* as string
  • 我想接受int as long
  • 我想给enum types

例如,在伪 C++ 代码中,我的希望:

class MyVariant : public boost::variant<char,bool,long,std::string>
{
  typedef boost::variant<char,bool,long,std::string> super;

public:    

  // I know here I should specialize templeted constructors
  // but I is more clear like that, isn't it?    
  MyVariant()              : super('e')             {} //empty -> char
  MyVariant(char        c) : super(std::string(1,c)){} //char  -> string
  MyVariant(const char* s) : super(std::string(s) ) {} //char* -> string
  MyVariant(int         v) : super(long       (v) ) {} //TODO boundaries    
  /* other constructors ... */

  enum Type
  {
    NONE,  //my empty state = char type
    BOOL,
    LONG,
    STRING
  };

  Type type() const { return (Type) which(); }    
};

基本片段代码(在问题之上)已在不同平台上进行了测试

  • 升压 v1.33 + GCC 4.1 (Linux)
  • 升压 v1.52 + GCC 4.7 (MinGW)
  • 升压 v1.52 + Visual C++ 2010 (v10)

下面是我对两个版本的 GCC 的错误 (如果有人打扰的话我可以删除其中之一......)


$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ myVariant.cpp
/usr/include/boost/variant/variant.hpp: In constructor 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&) [with T = MyVariant, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]':
myVariant.cpp:10:   instantiated from 'MyVariant::MyVariant(T&) [with T = MyVariant]'
myVariant.cpp:19:   instantiated from here
/usr/include/boost/variant/variant.hpp:1348: error: call of overloaded 'convert_construct(MyVariant&, long int)' is ambiguous
/usr/include/boost/variant/variant.hpp:1262: note: candidates are: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&, int, mpl_::false_) [with T = MyVariant, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]
/usr/include/boost/variant/variant.hpp:1321: note:                 void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char, U1 = bool, U2 = boost::detail::variant::void_, U3 = boost::detail::variant::void_, U4 = boost::detail::variant::void_, U5 = boost::detail::variant::void_, U6 = boost::detail::variant::void_, U7 = boost::detail::variant::void_, U8 = boost::detail::variant::void_, U9 = boost::detail::variant::void_, U10 = boost::detail::variant::void_, U11 = boost::detail::variant::void_, U12 = boost::detail::variant::void_, U13 = boost::detail::variant::void_, U14 = boost::detail::variant::void_, U15 = boost::detail::variant::void_, U16 = boost::detail::variant::void_, U17 = boost::detail::variant::void_, U18 = boost::detail::variant::void_, U19 = boost::detail::variant::void_, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]
/usr/include/boost/variant/variant.hpp:1330: note:                 void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char, U1 = bool, U2 = boost::detail::variant::void_, U3 = boost::detail::variant::void_, U4 = boost::detail::variant::void_, U5 = boost::detail::variant::void_, U6 = boost::detail::variant::void_, U7 = boost::detail::variant::void_, U8 = boost::detail::variant::void_, U9 = boost::detail::variant::void_, U10 = boost::detail::variant::void_, U11 = boost::detail::variant::void_, U12 = boost::detail::variant::void_, U13 = boost::detail::variant::void_, U14 = boost::detail::variant::void_, U15 = boost::detail::variant::void_, U16 = boost::detail::variant::void_, U17 = boost::detail::variant::void_, U18 = boost::detail::variant::void_, U19 = boost::detail::variant::void_, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]

$ g++ --version
g++.exe (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ myVariant.cpp -I /c/.../include/
In file included from c:/.../include/boost/variant.hpp:17:0,
                 from myVariant.cpp:1:
c:/.../include/boost/variant/variant.hpp: In instantiation of 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&) [with T = MyVariant; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]':
myVariant.cpp:9:66:   required from 'MyVariant::MyVariant(T&) [with T = MyVariant]'
myVariant.cpp:18:25:   required from here
c:/.../include/boost/variant/variant.hpp:1406:9: error: call of overloaded convert_construct(MyVariant&, long int)' is ambiguous
c:/.../include/boost/variant/variant.hpp:1406:9: note: candidates are:
c:/.../include/boost/variant/variant.hpp:1316:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&, int, mpl_::false_) [with T = MyVariant; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; mpl_::false_ = mpl_::bool_<false>]
c:/.../include/boost/variant/variant.hpp:1376:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char; U1 = bool; U2 = boost::detail::variant::void_; U3 = boost::detail::variant::void_; U4 = boost::detail::variant::void_; U5 = boost::detail::variant::void_; U6 = boost::detail::variant::void_; U7 = boost::detail::variant::void_; U8 = boost::detail::variant::void_; U9 = boost::detail::variant::void_; U10 = boost::detail::variant::void_; U11 = boost::detail::variant::void_; U12 = boost::detail::variant::void_; U13 = boost::detail::variant::void_; U14 = boost::detail::variant::void_; U15 = boost::detail::variant::void_; U16 = boost::detail::variant::void_; U17 = boost::detail::variant::void_; U18 = boost::detail::variant::void_; U19 = boost::detail::variant::void_; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
c:/.../include/boost/variant/variant.hpp:1385:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char; U1 = bool; U2 = boost::detail::variant::void_; U3 = boost::detail::variant::void_; U4 = boost::detail::variant::void_; U5 = boost::detail::variant::void_; U6 = boost::detail::variant::void_; U7 = boost::detail::variant::void_; U8 = boost::detail::variant::void_; U9 = boost::detail::variant::void_; U10 = boost::detail::variant::void_; U11 = boost::detail::variant::void_; U12 = boost::detail::variant::void_; U13 = boost::detail::variant::void_; U14 = boost::detail::variant::void_; U15 = boost::detail::variant::void_; U16 = boost::detail::variant::void_; U17 = boost::detail::variant::void_; U18 = boost::detail::variant::void_; U19 = boost::detail::variant::void_; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]

接受的答案和其他答案都没有回答这个问题。从 boost::variant 派生有充分的理由。

  • 您想将方法添加到变体中,以便它表现得更加多态
  • 你想继续使用boost::apply_visitor(visitor(), variant)不跳圈

这是一个类型的工作示例MyVariant继承自boost::variant。该代码需要 C++11 继承(复杂)构造函数boost::variant.

Edit:等号比较等运算符的实现boost::variant不会自动为派生类工作。这是(意外的)结果boost::variant实现后,它明确阻止使用模板与“外部”类型进行比较。可以通过显式重载来启用运算符,如示例所示。

#include<iostream>
#include<boost/variant.hpp>

struct type_size_visitor : public boost::static_visitor<unsigned> {
  template <typename T>
  unsigned operator()(const T&) const { return sizeof(T); }
};

template <typename... Types>
class MyVariant : public boost::variant<Types...>
{
  using base_type = boost::variant<Types...>;
public:
  // inherit constructors
  using base_type::base_type;

  // add a new method
  unsigned type_size() { return boost::apply_visitor(type_size_visitor(), *this); }

  /* Inheriting operators from boost::variant does not
     work as it normally would. We have to add explicit
     overloads for the operators we want to use.
  */
  bool operator==(const MyVariant& rhs) const {
    // cast rhs to base and delegate to operator in base
    return base_type::operator==(static_cast<const base_type&>(rhs));
  }
};

int main() {
  MyVariant<std::string, char> v;
  v = 1;
  std::cout << v.type_size() << " " << sizeof(char) << std::endl;
  v = std::string("foo");
  std::cout << v.type_size() << " " << sizeof(std::string) << std::endl;

  // comparison operators need workaround shown above
  MyVariant<std::string, char> a, b;
  a = 1; b = 1;
  assert(a == b);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现 boost::variant 派生类? 的相关文章

随机推荐

  • EntityFramework 类在更新后被删除?

    我更改了数据库模型 以便其中一个表外键接受空值 之后我去了我的 edmx文件并执行 从数据库更新模型 保存后 代表表的所有类文件都被自动删除 如果我恢复数据库中的更改并重新保存我的 edmx 类将重新出现 但我真的希望这个外键能够接受空值
  • 为什么所有Powershell输出没有写入txt文件

    我在 Powershell Core 中运行以下 Powershell 脚本 PS C gt Get ChildItem Recurse File Filter pbix Sort Object Property LastAccessTim
  • 上传到 S3 时 Lambda 函数超时

    我有一个用 python 编写的 lambda 函数 它在 mongodb 中执行一些操作 然后它应该将函数的 tmp 文件夹中的图片上传到 s3 上 该函数在上传步骤中不断超时 我将超时设置为 2 分钟 并且该函数具有 S3 和 vpc
  • 更改 jQuery UI 按钮大小?

    我一直在我的页面上使用 jQuery UI 按钮 但是我还没有找到解决这个看似简单问题的方法 我希望我的一些按钮比其他按钮小 这应该像将按钮文本的 CSS 设置为类似的内容一样简单 font 8em 然而 jQuery UI 获取你的 DO
  • SQL Server 2005的默认并发控制

    SQL Server 2005 的默认并发控制是什么 是乐观并发控制还是悲观并发控制 这个可以设置吗 感谢期待 悲观 似乎是 2005 年的默认设置 尽管可以根据需要激活快照隔离 在默认的悲观模型中 第一个写入者将阻止所有后续写入 作家 但
  • PreventDefault 不适用于焦点事件

    我正在尝试设计一种表单 如果它具有特定的类 则用户应该无法与任何输入进行交互 由于各种原因 我想避免使用 disabled 属性 我试图阻止焦点事件的默认设置 但它不起作用 我在最新版本的 Firefox Chrome 和 Android
  • TFS 签入成功后清除“评论”字段吗?

    在 Visual Studio 2013 中 是否可以让 TFS 在成功签入后自动清除 注释 字段 在 待更改 面板上 目前 我只是在每次签到后手动突出显示并删除评论字段文本 下面的例子 在我的签到中添加了评论 希望在成功签入后看到这一点
  • 不使用 ContentProvider 时使用 CursorLoader

    Android SDK 文档说startManagingCursor 方法已弃用 此方法已被弃用 使用新的 CursorLoader 类和 LoaderManager 代替 这也可以通过 Android 兼容包在旧平台上使用 此方法允许活动
  • 如何为 R 中使用 grid.arrange() 创建的每一列指定标题?

    有谁知道是否可以在使用 grid arrange 创建的图表的每一列上给出标题 我知道可以为每个图表提供总体标题和标题 但我只需要一个列标题 非常感谢 grid arrange c1b c2a c3d c2b c3a c2d c3b c1a
  • 使用 Laravel Envoy 部署到具有不同项目根的多个服务器

    使用 Laravel Envoy 部署到多个服务器时 如何指定每个服务器的项目根目录 文档中提供的示例假设项目根目录对于两台服务器来说是相同的路径 Assume web 1项目根目录为 var html www and web 2项目根目录
  • 如何使用自定义 Comparator 或 equals 方法查找 Set 差异?

    我想找到两者之间的区别Set
  • 任何设置了“Access-Control-Allow-Origin: *”标头的 jQuery 托管版本?

    我最近一直在使用 jQuery 遇到了一个问题 我无法将其包含在用户脚本中 因为 XmlHttpRequest 使用同源政策 http en wikipedia org wiki Same origin policy 经过进一步测试我发现大
  • 尝试生成 apk 时,android studio 中的 livedata$1.class 出现重复输入错误 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我真的不知道是什么导致了这个错误以及如何解决它 我的所有依赖 implementation fileTree dir l
  • 如何展平嵌套模型? (keras函数式API)

    我使用 keras 模型功能 API 定义了一个简单的模型 它的一层是一个完全顺序的模型 所以我得到了一个嵌套的层结构 见下图 如何将这种嵌套层结构转换为平面层结构 使用脚本 而不是手动 What I have Layer type Out
  • 无法将资源加载为 XML 文件

    我已经使用 XNA 完成了我的项目 目前我正在尝试使用 Monogame 对其进行转换 我的问题是我无法加载 XML 文件 错误 Could not load Level asset as a non content file 我的代码 f
  • C++03中函数返回类型推导

    标签提出了问题 但尽管如此 请考虑以下几点 template
  • 无法将“mysql2/promise”导入 Node.js 13 / 14 上的 ES 模块 (MJS)

    从 CommonJS 迁移时 cjs 到 ES 模块 mjs 我遇到了将命名空间 CJS 导入 MJS 的问题 import mysqlPromise from mysql2 promise 返回错误 错误 ERR MODULE NOT F
  • R 集群导出错误“未找到对象”

    有人可以帮助我理解为什么我的程序会产生此错误吗 从这里可以看出 pay freq 显然是环境的一部分 那么为什么找不到它呢 语法与 ts 相同 可以毫无问题地找到它 大圆圈部分覆盖了单词功能 小圆圈部分覆盖了单词情节 cf pro lt f
  • ASP.NET requestValidation 4.5 和 WIF

    我有一个 ASP NET MVC 应用程序 启用了 Windows Identity Foundation 身份验证 并使用 ADFS 作为 STS 该应用程序现在位于带有 MVC 4 的 NET 4 5 上 当我将 ASP NET req
  • 如何实现 boost::variant 派生类?

    我已经尝试了几个小时来编写一个派生类boost variant 但我不明白问题是什么 我不明白编译错误意味着什么 实施清洁的规则是什么boost variant派生类 include