歌词:
我尝试通过 MPI 实现一个任务池。所以我需要某种 RPC,但它可以在我程序的不同部分之间工作,这意味着处理器 A 希望处理器 B 使用参数 D 调用函数 C。我们不能像处理线程那样在进程之间传递指向函数的指针,所以我们需要一些包装容器来保存每个流程实例的函数指针。全部在一个源文件\一个程序中......所以我开始想知道如何在容器中存储具有不同签名的功能对象。我当时的 API 想法是错误的 - 最好在该池构造中定义函数池中的所有函数(至少它应该更容易实现)。但是在实施时我遇到了下一个麻烦:
问题:
这样的简单代码(function_types,mpl::vector,variant):
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>
#include <iostream>
#include <string>
template <class T>
int append(T val)
{
std::cout << "hello";
return 0;
}
int main()
{
boost::variant<boost::function_types::function_type< boost::mpl::vector<int,int> >::type , boost::function_types::function_type< boost::mpl::vector<int,std::string> >::type > a;
return 0;
}
不会编译落入:
Error 1 error C2066: cast to function type is illegal c:\program files\boost\include\boost\variant\variant.hpp 1231 1
查看源代码,我们看到:
这个代码块:
variant()
{
// NOTE TO USER :
// Compile error from here indicates that the first bound
// type is not default-constructible, and so variant cannot
// support its own default-construction.
//
new( storage_.address() ) internal_T0();
indicate_which(0); // zero is the index of the first bounded type
}
所以我想知道:如何解决这个错误?
我也试过:
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
template <class T>
int append(T val)
{
std::cout << "hello";
return 1;
}
int main()
{
boost::variant< boost::function<int (std::string) >, boost::function<int (int) > > a;
a= &append<int>;
return 0;
}
失败了:
Error 1 error C2668: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : ambiguous call to overloaded function c:\program files\boost\include\boost\variant\variant.hpp 1330
关于如何制作 boost.variant 保持功能的任何想法?
当然,我们可以像这样使用指向函子的共享指针:
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
template <class in, class out>
struct s_append
{
out operator()(in val) {
std::cout << "hello";
return out();
}
};
int main()
{
boost::variant<boost::shared_ptr<s_append<int, int> >, boost::shared_ptr< s_append<std::string, int> > > a;
boost::shared_ptr<s_append<int, int> > b(new s_append<int, int> );
a=b;
return 0;
}
它会编译,但生成的 API 很糟糕——你必须 1)为你想要使用的所有函数创建仿函数(意味着限制当前进程范围的使用);2)使用shared_pointers,所以我什至不知道如何以这种方式调用嵌套的函数(简单的第一个猜测(*a)(22);
就是不会编译=(并且API开始像我们使用Boost.Any那样糟糕)。