Текст:
Я пытаюсь реализовать пул задач через MPI.Поэтому мне нужен какой-то RPC, но тот, который будет работать между различными частями моей программы, то есть процессор A хочет, чтобы процессор B вызывал функцию C с аргументом D. Мы не можем передавать указатели на функции между процессами, как мы делаем с потоками, поэтому мынужен контейнер-обертка для хранения указателей на функции в каждом экземпляре процесса.Все внутри одного исходного файла \ одной программы ... Итак, я начал задумываться о Как хранить функциональные объекты с разными сигнатурами в контейнере .Моя идея API в то время была неправильной - лучше определить все функции в пуле функций при построении этого пула (по крайней мере, это будет намного проще реализовать).Но при реализации я столкнулся со следующей проблемой:
Проблема:
Такой простой код ( function_types , mpl :: vector , вариант ):
#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
И, глядя на source мы видим:
этот блок кода:
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).