组合一组容器类并从基础访问它们
我正在尝试使用 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
和其他向量不应该出现在类型层次结构中以供 static_cast 拉出吗?
还有其他方法可以实现此功能吗?
I'm trying to use boost::mpl::inherit_linearly
to compose a container class using types provided by the user:
#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;
}
The compile error I get is:
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> >&’
Shouldn't Base
be a base of whatever type is produced by inherit_linearly
? And if so, shouldn't a vector<int>
and the other vectors show up in the type hierarchy for static_cast to pull out?
Is there any other way to get this functionality?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为
Base
是InheritedContainer
的基类,但不是std::vector
。众所周知,
std::vector
的定义如下:您可能期望以下继承:
但是,在本例中,从
Base
到的转换>vector
是一个交叉转换,所以这不能用
static_cast
来完成。如您所知,以下是允许的:
如果您可以准备
get_container
、my_int_func
和my_char_func
,可能是以下类型std::vector
将专门针对哪些对象是事先已知的。如果是这样,我认为持有
InheritedContainer&
而不是Base&
是相关的一直以来。
如果您必须将
Base
转换为vector
,可能RTTI(例如将虚拟函数添加到
Base
)和dynamic_cast
将启用演员阵容。
I think
Base
is a base class ofInheritedContainer
, but not ofstd::vector<int>
.As we know,
std::vector
isn't defined as the following:You may expect the following inheritance:
However, in this case, the cast from
Base
tovector<int>
is a cross-cast,so this cannot be done with
static_cast
.As you may know, the following is allowed:
If you can prepare
get_container
,my_int_func
andmy_char_func
, probably the typesto which the
std::vector
will be specialized are known beforehand.If so, I suppose it is pertinent to hold
InheritedContainer&
instead ofBase&
all along.
If you have to cast
Base
tovector<T>
, probablyRTTI(for example adding virtual function to
Base
) anddynamic_cast
will enablethe cast.