我有一个超类,它根据它使用的一些内部类型定义。子类化如下执行:
template <class InternalType1, class InternalType2>
class Super
{
...
}
class Sub : Super <interalTypeClass1, interalTypeClass2>
{
...
}
但是当我想编写一个带有指向超类的指针的函数时,会发生这种情况:
template <class InternalType1, class InternalType2>
void function(Super<InternalType1, InternalType2>* in) { ... }
用户真的不应该对内部类有任何了解,而且应该只关心自己使用该函数。在我看来,这些模板列表中的一些变得非常大,并且期望用户每次都传递它们是浪费的。
有什么建议吗?
编辑:该函数需要知道正在使用的内部类型,所以除非有一种方法在编译时访问模板类型,我认为没有解决方案?
潜在的解决方案:让每个班级都做以下事情:
#define SubTemplateArgs <SubTypeName, SubInternalType1, SubInternalType2>
答案 0 :(得分:2)
template <class TInternal1, TInternal2>
class Super {
private:
/*...*/
public:
typedef TInternal1 internal_type_1;
typedef TInternal2 internal_type_2;
/*...*/
};
typedef Super<int, char> IntCharSuper;
typedef Super<bool, char> BoolCharSuper;
class Sub1 : IntCharSuper {/*...*/};
class Sub2 : IntCharSuper {/*...*/};
class Sub3 : BoolCharSuper {/*...*/};
/***
* functionA (below) can only take a pointer to an object of a
* class which inherits from IntCharSuper
**/
void functionA(IntCharSuper* in){
IntCharSuper::internal_type_1 internal1_variable;
IntCharSuper::internal_type_2 internal2_variable;
// we now have 2 variables of the internal types...
}
/***
* functionB (below) can take a pointer to an object of a class which inherits from any kind of Super,
* no matter what the template parameters of that Super are.
* so functionB will work for types which inherit from
* IntCharSuper, BoolCharSuper, Super<YourCustomType, void*>, or anything else for TInternal1 and TInternal2.
**/
template <class TSuper>
void functionB(TSuper* in) {
typename TSuper::internal_type_1 internal1_variable; /* typename is needed here */
typename TSuper::internal_type_2 internal2_variable; /* typename is needed here */
// we now have 2 variables of the internal types...
}
int main(int argc, const char* argv) {
Sub1 s1;
Sub2 s2;
Sub3 s3;
functionA(&s1); //OK, s1 inherits IntCharSuper
functionA(&s2); //OK, s2 inherits IntCharSuper
functionA(&s3); //ERROR, s3 hasnt got IntCharSuper as parent
functionB(&s2); //OK, s2 inherits from a class which defines internal_type_1 and internal_type_2
functionB(&s3); //OK, s3 inherits from a class which defines internal_type_1 and internal_type_2
return 0;
}
答案 1 :(得分:1)
您可以更改Super
界面
template <class Types>
class Super {
...
};
class SubTypes {
typedef interalTypeClass1 InternalType1;
typedef interalTypeClass2 InternalType2;
};
class Sub : public Super <SubTypes> {
...
};
然后您的功能模板看起来更加用户友好
template <class Types2>
void function(Super<Types>* in) {
...
}
Sub s;
// ...
function(&s);
但是用户不需要关心那些参数 - 如果用户传递了正确的函数参数,编译器会自己计算出模板参数。想想std::operator<<
和std::string
。后者实际上如下所示,T
为char
std::basic_string< T, std::char_traits<T>, std::allocator<T> >
将operator<<
打印到输出流真的接受这样的类型,C ++编码器仍然不需要关心分配器或字符特征。正确的文档可以让他们轻松地使用std::string
并将其传递出去并打印出来。
答案 2 :(得分:1)
用户真的不应该对内部类有任何了解,而且应该只关心自己使用该函数。
问题是每个不同的模板选项组合都定义了一个不同的类。
您无法执行以下操作
vector<Super<int,int>> a;
a.push_back( Super<float,float>() );
同样,你不想写的函数有同样的问题,你有多个函数重载。
您可以选择使用typedef命名各种组合(如已建议的那样),或者您可以使用Super所基于的更常见的父类。
class SuperDoooper {
virtual SomeMethod();
}
template <class InternalType1, class InternalType2>
class Super
{
SomeMethod() { InternalType1.. }
}
class Sub : Super <interalTypeClass1, interalTypeClass2>
{
...
}
function( SupoerDoooper *in ) { in->SomeMethod(); }
答案 3 :(得分:0)
将以下typedef添加到Sub类:
typedef Super<internalTypeClass1,internalTypeClass2> MySuper;
现在你可以写
了void function (Sub::MySuper *in);
答案 4 :(得分:0)
typedef的问题在于编译器在错误消息中使用完整的类名。也许这样的事情会更好:
class MySuper : public Super<internal1, internal2> {
// forward constructors
}