Boost.Variant, Boost.MPL: Как добавить типы? - PullRequest
0 голосов
/ 29 ноября 2011

Я смотрю на этот код решетки, основанный на boost.Any и не могу помочь, но не могу понять, можем ли мы вместо этого использовать Boost.Variant .Интересно, возможно ли такое API:

void voidFunc()
{
    std::cout << "void called" << std::endl;
}

int stringFunc(std::string str)
{
    std::cout << str << std::endl;
    return 0;
}

int main()
{
    some_map_like_type<std::string, boost::variant> funcs;
    funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void>
    funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string>
    funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type


    // And here when all the fun part is:
    funcs["voidFunc"](); // compiles
    funcs["stringFunc"]("hello"); // compiles
    funcs["stringFunc"](some_not_std_string_class); // does not compile.
    return 0;
}

Это означает, что в конце компилятор должен будет скомпилировать что-то вроде:

void voidFunc()
{
    std::cout << "void called" << std::endl;
}

int stringFunc(std::string str)
{
    std::cout << str << std::endl;
    return 0;
}

int main()
{
    some_map_like_type<std::string, boost::variant< boost::function<void , void>, boost::function<int , std::string> > > funcs;
    funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void>
    funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string>
    funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type


    // And here when all the fun part is:
    funcs["voidFunc"](); // compiles
    funcs["stringFunc"]("hello"); // compiles
    funcs["stringFunc"](some_not_std_string_class); // here it would give error and would not compile
    return 0;
}

Обновление:

Чтоя пытался (на основе этого Вариант документов и MPL и документов ):

#include <boost/static_assert.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/multiplies.hpp>
#include <boost/mpl/placeholders.hpp>

#include <boost/variant.hpp>
#include <iostream>
#include <string>
#include <vector>

class sudo_science
{
public:
    typedef  boost::mpl::vector_c<int> types_vector1;

    typedef boost::make_recursive_variant< types_vector1 >::type recursive_variant_t;

    std::vector< recursive_variant_t > variant_seq;

    template <typename T>
    void append(T val)
    {
        typedef  boost::mpl::push_back<types_vector1,T>::type types_vector1;
        variant_seq.push_back(val);
        return;
    }

    std::vector< recursive_variant_t > give_me_end_variant()
     {
         return variant_seq;
     }
};

int main()
{
    sudo_science a;
    a.append<float>(1.0);
    a.append<std::string>("Stack and Boost");

    //sorry for C++11
    auto varint = a.give_me_end_variant();

    return 0;
}

Но он не компилируется с2 одинаковые ошибки:

Error   1   error C2665: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : none of the 2 overloads could convert all the argument types    c:\program files\boost\include\boost\variant\variant.hpp    1330    1

1 Ответ

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

Это невозможно.operator[] - вещь времени выполнения, а типы - вещь времени компиляции.Так должен ли компилятор скомпилировать следующее?

char const* str;
if (some_condition())
  str = "voidFunc";
else
  str = "stringFunc";
// ... some more code
if (some_condition())
  funcs[str]();
else
  funcs[str](str);

Как компилятор должен знать, дает ли второй вызов some_condition() тот же результат, что и раньше?Или код между ними изменил значение str?

Как насчет следующего:

void call(some_map_like_type<std::string, boost::variant> const& funcs)
{
  funcs["voidFunc"]();
}

Как компилятор должен знать, содержит ли во время вызова funcsвходное сопоставление "voidFunc" функции без аргументов?И что должно произойти, если он вызывается один раз со значением, которое делает, и один раз со значением, которое не имеет?

В зависимости от того, чего вы на самом деле хотите 1017 *, могут возникнутьспособ получить его с помощью шаблонов и constexpr функций.Однако обратите внимание, что то, что происходит во время выполнения, не может повлиять на то, компилируется ли код, по той простой причине, что код не может быть выполнен до его компиляции.

...