我需要编写模板,根据模板参数是否为某个类的实例,生成一些代码。可以为所有类生成模板,但仅当该类是其他类的子类时才应该执行代码。
问题是应该实现的函数不接收类的任何实例,因此唯一已知的是类名。所以使用dynamic_cast是不可能的,因为它需要对象的实例
template<T>
class A
{
void somefunction(void)
{
if (T instanceof Foo) then ...
else ...
}
}
添加一些解释
class X: public Foo {};
class Y {};
class A<X> {} // special logic is generated
class A<Y> {} // special logic is NOT generated
答案 0 :(得分:3)
您可以使用boost traits library中的模板专精或boost :: is_base_of 或者当然要编写自己的特性,但不应该,因为你还没有掌握模板。
使用专业化,你可以
template<T>
class A
{
void somefunction() {
// generic version
}
};
template<>
class A <Foo>
{
void somefunction() {
// foo version
}
};
与往常一样,让我推荐Vandevoorde / Josuttis“C ++模板:完整指南”。
如果你担心代码膨胀,因为只有一个成员函数需要专门化,你仍然可以外包该函数:
template <typename T> struct somefunction_helper {
static void thatfunction () {
// generic form
}
};
template <> struct somefunction_helper<Foo> {
static void thatfunction () {
// Foo form
}
};
template<T>
class A
{
void somefunction() {
somefunction_helper<T>::thatfunction();
}
};
答案 1 :(得分:2)
这是模板专业化的用途。他们写作起来比较困难,但这就是你用它们做的事情。例如:
template<T> class A
{
void somefunction(void) {
...//default for any object type.
}
};
template<> class A<Foo>
{
void somefunction(void) {
...//specific to the type Foo.
}
};
是的,这需要额外的工作。有一些模板元编程方法可以按照你想要的方式做到这一点,但其他人必须解释这些。
答案 2 :(得分:1)
要么专门化A
,要么将someFunction()
成员函数模板的工作委托给一些你可以(完全)专注于T
的免费功能模板。
答案 3 :(得分:0)
由于模板参数只能从Foo
派生,因此专业化不起作用,请使用另一个答案:is_base_of
,来自Boost或来自标准库(如果它已经支持部件) C ++ 0x:
#include <type_traits> // C++0x
class Foo{};
template<class T>
class A{
void specialOnFoo(){
// dispatch the call
specialOnFoo(std::is_base_of<T, Foo>::type());
}
void specialOnFoo(std::true_type){
// handle Foo case
}
void specialOnFoo(std::false_type){
// non-Foo case
}
};
答案 4 :(得分:-1)
编辑#2 - 参见工作示例。请注意,这是模板特化的运行时等效项(在编译时发生)并且需要启用RTTI。
#include <iostream>
#include <typeinfo>
using namespace std;
class Foo {};
class X: public Foo {};
class Y {};
template<typename T> class A {
public:
void somefunction()
{
if (typeid(T) == typeid(X)) {
cout << "X specific logic happening" << endl;
}
else {
cout << "Default behavior" << endl;
}
}
};
int main() {
A<X> ax;
A<Y> ay;
ax.somefunction(); // prints "X specific logic happening"
ay.somefunction(); // prints "Default behavior"
}
typeid
可与模板一起使用以提取模板参数的类型 - 如下所述:
// expre_typeid_Operator_3.cpp
// compile with: /c
#include <typeinfo>
template < typename T >
T max( T arg1, T arg2 ) {
cout << typeid( T ).name() << "s compared." << endl;
return ( arg1 > arg2 ? arg1 : arg2 );
}
取自:http://msdn.microsoft.com/en-us/library/fyf39xec(v=vs.80).aspx
请注意,name()
的值是实现定义的。