2011-03-17 39 views
1

我試圖用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> >&’ 

不應該Baseinherit_linearly產生的任何類型的基礎?如果是這樣,不應該vector<int>和其他向量顯示在static_cast的類型層次結構拉出?

有沒有其他的方式來獲得這個功能?

回答

0

我認爲BaseInheritedContainer的基類,但不是 std::vector<int>。 正如我們所知,std::vector沒有定義如下:

class vector : Base {... 

你可以期待以下繼承:

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

然而,在這種情況下,從Base投給vector<int>是一個跨-cast, 所以這不能用static_cast來完成。

正如你可能知道,下面是允許的:

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

如果你可以準備get_containermy_int_funcmy_char_func,可能是類型 到該std::vector將以專業化是事先知道的。 如果是這樣,我認爲它一直持有InheritedContainer&而不是Base&
如果你要投Basevector<T>,大概 RTTI(例如添加虛擬功能Base)和dynamic_cast將使 投。