将成员函数集调用为特定变体的正确 C++ 变体语法是啥?

Posted

技术标签:

【中文标题】将成员函数集调用为特定变体的正确 C++ 变体语法是啥?【英文标题】:What is the right c++ variant syntax for calling a member function set to a particular variant?将成员函数集调用为特定变体的正确 C++ 变体语法是什么? 【发布时间】:2016-07-08 19:54:14 【问题描述】:

下面的代码使用包含 int/MyVariant 对的 std::map 的 boost 变体。我能够正确初始化我的地图,其中第一个元素包含 33/A 对,第二个元素包含 44/B 对。 A 和 B 各有一个函数,我希望能够在分别检索到它们的初始化地图元素后调用它:

#include "stdafx.h"
#include "boost/variant/variant.hpp"
#include "boost/variant/get.hpp"
#include "boost/variant/apply_visitor.hpp"
#include <map>

struct A  void Fa()  ;
struct B  void Fb()  ;

typedef boost::variant< A, B > MyVariants;
typedef std::map< const int, MyVariants > MyVariantsMap;
typedef std::pair< const int, MyVariants > MyVariantsMapPair;

struct H

  H( std::initializer_list< MyVariantsMapPair > initialize_list ) : myVariantsMap( initialize_list ) 

  MyVariantsMap myVariantsMap;
;

int main()

  H h   33, A  ,  44, B    ;

  auto myAVariant = h.myVariantsMap[ 33 ];
  auto myBVariant = h.myVariantsMap[ 44 ];

  A a;
  a.Fa(); // ok

  // but how do I call Fa() using myAVariant?
   //myAVariant.Fa(); // not the right syntax

  return 0;

这样做的正确语法是什么?

【问题讨论】:

你试过boost::get&lt;A&gt;(myAVariant).Fa()吗? 是的。问题在于,变体信息必须应用两次。插入地图对时一次,检索地图对时一次。应该是 IMO 一次。 从编译器的角度来看,通过使用变体,您可以擦除信息什么是变量的真实类型。 C++ 仍然是强类型语言,因此信息应该在某个时候提供回来...... 也许 boost 变体不是强类型的,但建议的 c++17 std::variant 至少被称为强类型。 我认为你想要的变体工作需要 c++ 对模板函数结果进行推演......不幸的是我认为 c++17 不会引入它...... 【参考方案1】:

boost::variant 方法是使用访问者:

#include <boost/variant/variant.hpp>
#include <map>
#include <iostream>
struct A  void Fa() std::cout << "A" << std::endl; ;
struct B  void Fb() std::cout << "B" << std::endl;  ;

typedef boost::variant< A, B > MyVariants;
typedef std::map< const int, MyVariants > MyVariantsMap;
typedef std::pair< const int, MyVariants > MyVariantsMapPair;

struct H

  H( std::initializer_list< MyVariantsMapPair > initialize_list ) : myVariantsMap( initialize_list ) 

  MyVariantsMap myVariantsMap;
;


class Visitor
    : public boost::static_visitor<>

public:

    void operator()(A& a) const
    
        a.Fa();
    

    void operator()(B& b) const
    
        b.Fb();
    

;

int main()

  H h   33, A  ,  44, B    ;

  auto myAVariant = h.myVariantsMap[ 33 ];
  auto myBVariant = h.myVariantsMap[ 44 ];

  boost::apply_visitor(Visitor(), myAVariant);
  boost::apply_visitor(Visitor(), myBVariant);

  return 0;

live example

【讨论】:

以上是关于将成员函数集调用为特定变体的正确 C++ 变体语法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

这种自调用匿名函数变体背后的原因

C++ Boost 变体错误

将多个变体组合成一个变体

比较变体内容的函数无法编译

WooCommerce 中特定产品变体的自定义后缀

BigQuery/SQL - 特定变体的拆分值