模板&多态类 [英] templates & polymorphic classes
问题描述
我在设计特定版本的auto_ptr
时遇到的一个问题是,我必须在多态和多态之间进行区分。参数和平原一个,
因为模板必须在内部转换为void *。
具体来说,
模板< typename T> ; void f(T * t){
void * p = dynamic_cast< void *>(t);
}
$ b $如果T不是一个至少具有某个虚拟函数的类,那么b将无法编译。特别是,没有一个STL容器可以为T确定
。
然而,由于多重继承,如果我想要到达基数
大多数 class,dynamic_cast< void *>是要走的路。
我可以使用reinterpret_cast,这对所有的T,
都有效,除非我失去了施放到基地上面提到的功能。
我也可以使用一对模板,一个用于多态类型,
和一个POD。但我宁愿不这样做。
我会对运行时查询感到满意......如果我可以设计一个,那就是。
typeid()似乎不适用于这种情况。
理想情况下,如果我能想出
模板< typename T>
bool is_polymorphic(T t){
...
}
我会满心欢喜:-)
任何接受者?
-
JFB
verec写道:
我在设计特定版本时遇到了一个问题auto_ptr
是我必须在多态和多态之间进行区分。参数和普通
一些,因为模板必须在内部转换为void *。
具体来说,
模板< typename T> void f(T * t){
void * p = dynamic_cast< void *>(t);
}
如果T不是,则无法编译至少具有虚拟功能的类。
它不会工作,因为dynamic_cast只能在一个类
层次结构中运行,而''void''不属于它。它对我来说似乎没有多大的意义。如何以及为什么你想要一个动态广播来判断某个对象是否来自''void'?为什么不只是
static_cast?
特别是,没有一个STL容器确实符合T.
然而,因为多重继承,如果我想要到达基地最的话。 class,dynamic_cast< void *>是要走的路。
编号''void''不是基类。
我可以使用reinterpret_cast代替,这对所有T都适用,>除了我失去了施放到基地之外上面提到的功能。
我没有看到你需要的东西。
我也可以使用一对模板,一个用于多态类型,一个和一个POD。但我宁愿不这样做。
我会对运行时查询感到满意......如果我可以设计一个,那就是。
为什么?
typeid()似乎不适用于这种情况。
理想情况下,如果我能上来用
模板< typename T>
bool is_polymorphic(T t){
...
}
我会被填满很高兴:-)
任何接受者?
2005-06-16 00:26:40 + 0100,Rolf Magnus< ra ****** @ t-online.de>说:
如果T不是一个至少具有虚拟功能的类,则不会编译。
它不会工作,因为dynamic_cast只能在一个类层次结构中工作,而''void''不属于它。对我来说似乎也没什么意义。你想要一个动态广播如何以及为什么要尝试检查一个对象是否来自''void'?为什么不只是
static_cast?
对不起,我并没有让自己清楚。一个实际的例子
可能会有所帮助。考虑:
模板< typename T> struct my_ptr {
void * rawValue;
my_ptr(T * t):rawValue(dynamic_cast< void *>(t)){
}
};
struct polymorphic {
virtual~polyorphicic();
} ;
struct pod {
};
typedef my_ptr< polymorphic> Poly;
typedef my_ptr< pod> Pod;
void
test_00005(){
Poly p(new polymorphic);
// Pod pp(新pod);
}
如果我离开Pod pp行注释掉,一切都编译和工作
罚款。但是,如果我取消注释它,我会得到:
### error:不能dynamic_cast''t''(类型''struct pod *'')键入''void *''
###(源类型不是多态的)
我所追求的是一种在上面定义''my_ptr'以便它处理的方法br />
正确使用多态和POD结构。在多态的情况下需要
dynamic_cast。结构是因为当使用
MI时,dynamic_cast保证你得到一个指针返回基础对象的
,无论派生的是什么分支
用于T.
如果还有什么不清楚,请告诉我。
我想要的只是一个写一次,随处运行 (TM :-)模板,我可以在所有地方使用,而不必先询问,我是否使用吊舱或聚合物交易
? ;
非常感谢。
-
JFB
-
帮助您的用户:给他们风格: http://www.uiwithstyle .org
verec写道:2005-06-16 00:26:40 +0100, Rolf Magnus< ra ****** @ t-online.de>说:
如果T不是一个至少具有虚拟功能的类,则不会编译。
它永远不会工作,因为dynamic_cast只能在一个类层次结构中工作,而''void''不属于它。对我来说似乎也没什么意义。你想要一个动态广播如何以及为什么要尝试检查一个对象是否来自''void'?为什么不只是
static_cast?
对不起,我没有让自己清楚。一个实际的例子可能会有所帮助。考虑:
模板< typename T> struct my_ptr {
void * rawValue;
my_ptr(T * t):rawValue(dynamic_cast< void *>(t)){
无需使用''dynamic_cast''将指针转换为对象
为void *。它是可转换_Implicitly_。
}
};
struct polymorphic {
virtual~polyorphicic();
};
struct pod {
};
typedef my_ptr< polymorphic> Poly;
typedef my_ptr< pod> Pod;
void
test_00005(){
Poly p(new polymorphic);
// Pod pp(新pod);
}
如果我离开Pod pp一行注释,一切编译和工作
罚款。但是,如果我取消注释它,我会得到:
### error:不能dynamic_cast''t''(类型''struct pod *'')键入''void *''
###(源类型不是多态的)
我所追求的是一种在上面定义''my_ptr'的方法,以便它正确处理多态和POD结构。在多态的情况下需要
dynamic_cast。结构是因为当使用MI时,dynamic_cast保证你得到一个指针返回基础对象,无论派生的哪个分支被用于T.
基础对象是什么?你存储的指针是''void *''!
如果还有什么不清楚的地方,请告诉我。
天哪,是的。也许你可以发布_real_''my_ptr''类。
我想要的只是写一次,随处运行。 (TM :-)模板,我可以在任何地方使用,而不必先询问,我是否用吊舱或聚合物处理
?>
您还应该尝试显示_how_您将使用类型为
''my_ptr''的对象。 我可以在所有地方使用是一个过于模糊的陈述,是任何价值的b $ b。
V
One problem I''ve come accross in designing a specific version of auto_ptr
is that I have to disntiguish between "polymorphic" arguments and "plain" ones,
because the template has to, internally, cast to void *.
Specifically,
template <typename T> void f(T * t) {
void * p = dynamic_cast<void *>(t) ;
}
will not compile if T isn''t of a class that has somewhere at least
a virtual function. In particular, none of the STL containers do qualify
for T.
Yet, because of multiple inheritance, if I want to get down to the base
"most" class, the dynamic_cast<void*> is the way to go.
I could use reinterpret_cast instead, and this would work for all T,
except that I''d lose the "cast to base" feature mentionned above.
I could also use a pair of templates, one for polymorphic types,
and one of "POD". But I''d rather not do that.
I''d be happy with a runtime query ... if I could devise one, that is.
typeid() seems to not be applicable in this context.
Ideally, if I could come up with
template <typename T>
bool is_polymorphic(T t) {
...
}
I would be filled with joy :-)
Any taker?
--
JFB
verec wrote:
One problem I''ve come accross in designing a specific version of auto_ptr
is that I have to disntiguish between "polymorphic" arguments and "plain"
ones, because the template has to, internally, cast to void *.
Specifically,
template <typename T> void f(T * t) {
void * p = dynamic_cast<void *>(t) ;
}
will not compile if T isn''t of a class that has somewhere at least
a virtual function.
It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?
In particular, none of the STL containers do qualify
for T.
Yet, because of multiple inheritance, if I want to get down to the base
"most" class, the dynamic_cast<void*> is the way to go.
No. ''void'' is not the base class.
I could use reinterpret_cast instead, and this would work for all T,
except that I''d lose the "cast to base" feature mentionned above.
I fail to see what you need that for.
I could also use a pair of templates, one for polymorphic types,
and one of "POD". But I''d rather not do that.
I''d be happy with a runtime query ... if I could devise one, that is.
What for?
typeid() seems to not be applicable in this context.
Ideally, if I could come up with
template <typename T>
bool is_polymorphic(T t) {
...
}
I would be filled with joy :-)
Any taker?
On 2005-06-16 00:26:40 +0100, Rolf Magnus <ra******@t-online.de> said:
will not compile if T isn''t of a class that has somewhere at least
a virtual function.
It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?
I''m sorry I didn''t make myself clear enough. An actual example will
probably help. Consider:
template <typename T> struct my_ptr {
void * rawValue ;
my_ptr(T *t) : rawValue(dynamic_cast<void *>(t)) {
}
} ;
struct polymorphic {
virtual ~polymorphic() ;
} ;
struct pod {
} ;
typedef my_ptr<polymorphic> Poly ;
typedef my_ptr<pod> Pod ;
void
test_00005() {
Poly p(new polymorphic) ;
// Pod pp(new pod) ;
}
If I leave the "Pod pp" line commented out, everything compiles and works
fine. However, if I uncomment it, I get:
### error: cannot dynamic_cast ''t'' (of type ''struct pod*'') to type ''void*''
### (source type is not polymorphic)
What I am after, is a way to define ''my_ptr'' above so that it deals
correctly with both polymorphic and POD structs. The need for the
dynamic_cast in the case of "polymorphic" structs is because when
MI is used, dynamic_cast guarantees that you get a pointer back to
the base object, no matter what branch of the derivation has been
used for T.
If anything is still unclear, please, let me know.
All I want is a "write once, run anywhere" (TM :-) template that I
can use all over the place, without having to ask first, "Am I dealing
with a pod or a poly?"
Many Thanks.
--
JFB
--
Do your users a favor: give them Style: http://www.uiwithstyle.org
verec wrote:On 2005-06-16 00:26:40 +0100, Rolf Magnus <ra******@t-online.de> said:will not compile if T isn''t of a class that has somewhere at least
a virtual function.
It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?
I''m sorry I didn''t make myself clear enough. An actual example will
probably help. Consider:
template <typename T> struct my_ptr {
void * rawValue ;
my_ptr(T *t) : rawValue(dynamic_cast<void *>(t)) {
There is no need to use ''dynamic_cast'' to convert a pointer to an object
to void*. It''s convertible _implicitly_.
}
} ;
struct polymorphic {
virtual ~polymorphic() ;
} ;
struct pod {
} ;
typedef my_ptr<polymorphic> Poly ;
typedef my_ptr<pod> Pod ;
void
test_00005() {
Poly p(new polymorphic) ;
// Pod pp(new pod) ;
}
If I leave the "Pod pp" line commented out, everything compiles and works
fine. However, if I uncomment it, I get:
### error: cannot dynamic_cast ''t'' (of type ''struct pod*'') to type ''void*''
### (source type is not polymorphic)
What I am after, is a way to define ''my_ptr'' above so that it deals
correctly with both polymorphic and POD structs. The need for the
dynamic_cast in the case of "polymorphic" structs is because when
MI is used, dynamic_cast guarantees that you get a pointer back to
the base object, no matter what branch of the derivation has been
used for T.
To what base object? The pointer you store is ''void*''!
If anything is still unclear, please, let me know.
Hell, yes. Perhaps you could post the _real_ ''my_ptr'' class.
All I want is a "write once, run anywhere" (TM :-) template that I
can use all over the place, without having to ask first, "Am I dealing
with a pod or a poly?"
You should also try to show _how_ you''re going to use an object of type
''my_ptr''. "I can use all over the place" is too vague a statement to be
of any value.
V
这篇关于模板&多态类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!