指向带有 boost::variant 的成员函数的指针

Posted

技术标签:

【中文标题】指向带有 boost::variant 的成员函数的指针【英文标题】:pointers to member functions with boost::variant 【发布时间】:2011-12-07 18:18:46 【问题描述】:

我正在尝试定义一个指向成员函数的“通用”指针,该指针可用于访问特定类中的各种成员函数,如下所示:

class Security
    inline std::vector<double> member_function(const std::string &input_data_string) return ... a vector<double>....;;
    ;

我正在定义一个指向成员函数的通用指针,该成员函数可用于通过使用 boost::variant 访问“其他”函数以及具有不同返回类型和不同类型参数的函数。

typedef boost::variant<std::string,double, std::vector<double>, std::vector<std::string>>  (Security::*ptr_sec_fn)(boost::variant<std::string,double, std::vector<double>, std::vector<std::string>> );

然后将指针赋值给成员函数

    ptr_sec_fn=&Security::member_function;

这是我得到的错误:

cannot convert from 'std::vector<_Ty> (__thiscall Security::* )(const std::string &)' to 'boost::variant<T0_,T1,T2,T3> (__thiscall Security::* )(boost::variant<T0_,T1,T2,T3>)'
1>          with
1>          [
1>              _Ty=double
1>          ]
1>          and
1>          [
1>              T0_=std::string,
1>              T1=double,
1>              T2=std::vector<double>,
1>              T3=std::vector<std::string>
1>          ]
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

你能帮我找出我在这里做错了什么吗?非常感谢。

【问题讨论】:

您是否考虑过改用boost::functionstd::function 另请查看boost::bindboost::phoenix::bind 【参考方案1】:

这种方式是行不通的。有人必须进行从向量到变体类型的转换,而您的函数不能这样做(因为它返回一个向量,这就是它所知道的全部)并且创建指针的代码也不能这样做(因为它不能即时创建函数)。

另一方面,您可能还是想重新考虑您的设计。为什么你仍然需要一个这样的通用函数指针?可以更具体地指定吗?一个好的设计通过清晰的类型来展示自己,因为类型比任何文档都更准确地向程序员展示了所需的数据。

【讨论】:

我这样做是因为我不想每次我想调用不同的成员函数时都重新定义指针,尽管每次我调用该函数时我都知道它的返回类型。如果我要通过指针调用函数,我该如何进行转换: ptr_sec_fn=&(boost::get<:vector>>Security::member_function).. 不确定这是否是语法有效!【参考方案2】:

Security::member_function 的类型是 std::vector&lt;Ty&gt; (_thiscall Security::* )(const std::string &amp;),这与您尝试分配给它的指针的类型完全不同。这是不允许的。您只能将接受并返回该变量的成员函数分配给该类型的成员函数指针。

如果这个赋值有效,那么试图调用你的成员函数指针的代码会将一个变体传递给函数,并且该函数将被破坏,因为它需要一个字符串。任何地方都没有足够的信息让任何人知道有人需要以某种方式从您的变体中获取字符串。即使所有这些都奏效了,当函数返回一个向量时,有人需要知道该向量需要用于构造一个变体。这必须在调用站点完成,但调用站点甚至不知道正在返回向量。您知道返回的类型是不够的,编译器必须知道这一点。而你知道类型的事实表明你不应该首先使用包罗万象的类型。你应该使用正确的类型。

如果您有一堆接受和返回不同类型的重载函数,那么您将无法拥有一个可以指向任何这些重载的成员函数指针。尝试这样做完全忽略了 C++ 中的类型安全。所以你必须想出一种类型安全的方法来做你想做的事。

我们需要有关您的目标的更多信息,以帮助您找到实现目标的方法,但您目前正在尝试的方法永远不会奏效。

【讨论】:

以上是关于指向带有 boost::variant 的成员函数的指针的主要内容,如果未能解决你的问题,请参考以下文章

利用 boost-variant 创建带有 boost::mpl::for_each 的通用工厂方法

boost::variant:递归向量类型的奇怪行为

将由 boost::variant 聚合的类型的对象传递给接受该 boost::variant 的函数

Boost::Variant 和其中的 function_types:如何将函数放入 Boost::variant?

boost.variant 派生类型:不能使用复制构造函数

boost::variant 中持有的类的复制构造函数的问题