C++ 推断模板中的子类模板类型
我有一个从模板类派生的类:C++ 推断模板中的子类模板类型,c++,templates,inheritance,C++,Templates,Inheritance,我有一个从模板类派生的类: template <typename A,typename B> class TemplatedClass { }; class Hello : public TemplatedClass<int,float> { }; 我该怎么做 编辑: 我想传递类Hello,并让模板推断其子类TemplatedClass使用的类型 因此,当我创建一个类Check时,它将得到int和float类型 我无法将TemplatedClass更改为包含typ
template <typename A,typename B>
class TemplatedClass {
};
class Hello : public TemplatedClass<int,float>
{
};
我该怎么做
编辑:
我想传递类Hello,并让模板推断其子类TemplatedClass使用的类型
因此,当我创建一个类Check
时,它将得到int和float类型
我无法将TemplatedClass更改为包含typedef(它来自外部.lib) 编辑: 我已将模板更改为使用类,但出现以下错误:
错误C3200:“Hello”:模板参数“C”的模板参数无效,应为类模板。您可以执行以下操作:
template <template <typename A,typename B> typename C>
class Check
{
template<typename A, typename B>
void Foo(A a, B b) {
// C<A,B> would reconstruct the template type
}
}
// use:
Check<Hello> a;
a.Foo(true,1.f);
模板
课堂检查
{
模板
无效Foo(A,B){
//C将重建模板类型
}
}
//使用:
检查a;
a、 Foo(正确,1.f);
或者,这(你的意图并不明确):
模板
类模板类{
typedef A TypeA;
typedef B TypeB;
};
模板
课堂检查
{
void Foo(typename C::TypeA&a,typename C::TypeB&){}
}
//使用:
检查a;
a、 Foo(1,1.f);
尝试以下方法:
template <typename A,typename B>
class TemplatedClass {
public:
typedef A firstType;
typedef B secondType;
};
class Hello : public TemplatedClass<int,float>
{
public:
typedef firstType Type1;
typedef secondType Type2;
};
template <typename C>
class Check
{
typedef typename C::Type1 A;
typedef typename C::Type2 B;
void Foo(A,B,C)
{
// A is int .. B is float .. C is Hello
}
};
template <typename A, typename B>
class HelloBase : public TemplatedClass<A, B>
{
public:
typedef A Type1;
typedef B Type2;
};
typedef HelloBase<int, float> Hello;
template <typename C>
class Check
{
typedef typename C::Type1 A;
typedef typename C::Type2 B;
void Foo(A,B,C)
{
// A is int .. B is float .. C is Hello
}
};
...
Check<Hello> a;
模板
类模板类{
公众:
typedef是第一种类型;
类型定义B第二类型;
};
类你好:公共模板类
{
公众:
typedef第一种Type1;
typedef第二类Type2;
};
模板
课堂检查
{
typedef typename C::type1a;
typedef typename C::type2b;
无效Foo(A、B、C)
{
//A是int..B是float..C是Hello
}
};
我认为可以通过为Hello创建一个模板类,然后键入定义它的专门化来实现。比如:
template <typename A,typename B>
class TemplatedClass {
public:
typedef A firstType;
typedef B secondType;
};
class Hello : public TemplatedClass<int,float>
{
public:
typedef firstType Type1;
typedef secondType Type2;
};
template <typename C>
class Check
{
typedef typename C::Type1 A;
typedef typename C::Type2 B;
void Foo(A,B,C)
{
// A is int .. B is float .. C is Hello
}
};
template <typename A, typename B>
class HelloBase : public TemplatedClass<A, B>
{
public:
typedef A Type1;
typedef B Type2;
};
typedef HelloBase<int, float> Hello;
template <typename C>
class Check
{
typedef typename C::Type1 A;
typedef typename C::Type2 B;
void Foo(A,B,C)
{
// A is int .. B is float .. C is Hello
}
};
...
Check<Hello> a;
模板
类HelloBase:公共模板类
{
公众:
typedef A Type1;
typedef B Type2;
};
打招呼;
模板
课堂检查
{
typedef typename C::type1a;
typedef typename C::type2b;
无效Foo(A、B、C)
{
//A是int..B是float..C是Hello
}
};
...
检查a;
因此TemplatedClass不需要更改,您可以将要在Hello中输入的所有内容都放入HelloBase(使用模板作为一种工具来简单地携带类型)。首先,将
typename
更改为class
,§14.1[temp.param]p1
:
类型参数:
- 类标识符
- 类标识符opt=类型id
- 类型名标识符
- typename identifieropt=类型id
- 模板类标识符
- 模板classidentifieropt=id表达式
template<class T>
class Check;
template< // not 'typename' vvvvv
template<typename,typename> class C,
typename A, typename B
>
struct Check<C<A,B> >{
// ...
};
您可以将以下typedef添加到Hello
类中:
class Hello
: TemplatedClass<int,float>
{
public:
typedef TemplatedClass<int,float> base_type;
};
在一般情况下,您想要的是不可能的-如果两次从
TemplatedClass
派生出Hello
该怎么办
然而,在C++0x环境下,即使是非侵入式的操作,也相当简单
template<typename A, typename B> struct retval {
typedef A first;
typedef B second;
};
template<typename one, typename two> one first(const TemplatedClass<one, two>& ref);
template<typename one, typename two> two second(const TemplatedClass<one, two>& ref);
template<typename T> class Check {
typedef decltype(first(*static_cast<T*>(nullptr))) first;
typedef decltype(second(*static_cast<T*>(nullptr))) second;
};
模板结构检索{
第一类;
类型定义B秒;
};
第一个模板(const TemplatedClass&ref);
模板2秒(const TemplatedClass&ref);
模板类检查{
typedef decltype(第一个(*static_cast(nullptr)))第一个;
typedef decltype(second(*static_cast(nullptr)))second;
};
在C++03中,您仍然可以在方法内部获取参数,但无法在外部访问它们,除非插入特殊的typedef。我已经编辑了这个问题,希望它更清晰一些。我真的无法将TemplatedClass更改为包含typedefs(它来自一个外部的.lib),我已经设法让您的第一个建议起作用了,它需要是C类而不是typename。但它仍然不起作用,我已经在问题中添加了错误。我无法真正更改TemplatedClass以包含typedefs(它来自外部.lib),但这是个好主意。编辑了我的答案,我忽略了/误解了一些内容。不过,这个错误几乎暗示了您的想法有什么问题:
Hello
不是一个模板。请参阅我的答案。我知道这不是模板:这就是为什么我在这里要求,不能正确地到达基类<代码>类型名< /COD>和template<class T>
class CheckInternal;
template<
template<typename,typename> class C,
typename A, typename B
>
class CheckInternal<C<A,B> >{
public:
typedef A type_A;
typedef B type_B;
};
template<class T>
class Check{
typedef typename T::base_type T_base_type;
typedef typename CheckInternal<T_base_type>::type_A type_A;
typedef typename CheckInternal<T_base_type>::type_B type_B;
void foo(type_A a, type_B b){
// ...
}
};
// usage:
C<Hello> c; // OK!
template<typename A, typename B> struct retval {
typedef A first;
typedef B second;
};
template<typename one, typename two> one first(const TemplatedClass<one, two>& ref);
template<typename one, typename two> two second(const TemplatedClass<one, two>& ref);
template<typename T> class Check {
typedef decltype(first(*static_cast<T*>(nullptr))) first;
typedef decltype(second(*static_cast<T*>(nullptr))) second;
};