Составление набора контейнерных классов и доступ к ним из базы - PullRequest
1 голос
/ 17 марта 2011

Я пытаюсь использовать boost::mpl::inherit_linearly для создания класса контейнера, используя типы, предоставленные пользователем:

#include <typeinfo>
#include <iostream>
#include <vector>

#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/vector.hpp>

namespace mpl = ::boost::mpl;

//////////////////////////////////////////////
// Create the container by chaining vectors
//////////////////////////////////////////////

struct Base {};

// Types provided by the user
typedef mpl::vector<int, char, double>::type myTypes;

typedef mpl::inherit_linearly<
    myTypes, 
    mpl::inherit<mpl::_1, std::vector<mpl::_2> >,
    Base
    >::type InheritedContainer;


// Function for accessing containers
template <typename T>
inline std::vector<T>& get_container(Base& c) {
    return static_cast<std::vector<T>& >(c);
}


// Some functions that manipulate the containers
//     NB: These functions only know about the Base and the types
//         they want to access

void my_int_func(Base& b) {
    get_container<int>(b).push_back(42);
}

void my_char_func(Base& b) {
    get_container<char>(b).push_back('c');
}

int main() {
    InheritedContainer container;
    Base& bref = container;

    my_int_func(bref);
    std::cout << "Int: " << get_container<int>(bref).back() << std::endl;

    my_char_func(bref);
    std::cout << "Char: " << get_container<char>(bref).back() << std::endl;

    return 0;
}

Я получаю ошибку компиляции:

question.cpp: In function ‘std::vector<T, std::allocator<_CharT> >& get_container(Base&) [with T = int]’:
question.cpp:40:   instantiated from here
question.cpp:31: error: invalid static_cast from type ‘Base’ to type ‘std::vector<int, std::allocator<int> >&’
question.cpp: In function ‘std::vector<T, std::allocator<_CharT> >& get_container(Base&) [with T = char]’:
question.cpp:44:   instantiated from here
question.cpp:31: error: invalid static_cast from type ‘Base’ to type ‘std::vector<char, std::allocator<char> >&’

Не должно ли Base быть базой любого типа, производимого inherit_linearly? И если так, то не должен ли vector<int> и другие векторы отображаться в иерархии типов, чтобы static_cast мог их извлечь?

Есть ли другой способ получить эту функциональность?

1 Ответ

0 голосов
/ 17 марта 2011

Я думаю, Base - это базовый класс InheritedContainer, но не std::vector<int>.Как мы знаем, std::vector не определяется следующим образом:

class vector : Base {...

Можно ожидать следующее наследование:

class InheritedContainer : Base, std::vector<int>, ... {...

Однако в этом случае приведение от *От 1011 * до vector<int> является перекрестным броском, поэтому этого нельзя сделать с помощью static_cast.

Как вы, возможно, знаете, допускается следующее:

InheritedContainer container;
Base& bref = container;
InheritedContainer& iref = static_cast<InheritedContainer&>(bref);
std::vector<int>& vi = iref;
std::vector<char>& vc = iref;

Если вы можетеподготовьте get_container, my_int_func и my_char_func, вероятно, типы, для которых будет std::vector, известны заранее.Если это так, я полагаю, что целесообразно все время удерживать InheritedContainer& вместо Base&.
Если вам нужно привести Base к vector<T>, возможно RTTI (например, добавив виртуальную функцию к Basedynamic_cast включит приведение.

...