Boost :: Variant и function_types в нем: Как поместить функции в Boost :: варианту? - PullRequest
1 голос
/ 30 ноября 2011

Текст:

Я пытаюсь реализовать пул задач через 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).

1 Ответ

0 голосов
/ 30 ноября 2011

Попробуйте вставить фиктивный тип в качестве первого аргумента variant.Как объясняет найденный вами комментарий, только первый тип в варианте используется для собственного конструктора варианта по умолчанию.Вы можете использовать пустой тип структуры для этого (struct NoFunction {};).

Тем не менее, вы, возможно, задумывались над тем, чтобы использовать boost :: functions в качестве типов в варианте ... онипо умолчанию конструируемый по крайней мере.Я не уверен, чем вызвана другая ошибка, возникшая в результате этого подхода, но я просто хотел сообщить, что вы можете использовать этот угол больше, если не можете использовать обходной путь фиктивного типа, о котором я говорил.

...