推断模板中的子类模板类型
Infer subclass template types in a template
我有一个派生自模板类的类:
template <typename A,typename B>
class TemplatedClass {
};
class Hello : public TemplatedClass<int,float>
{
};
现在,我想制作一个模板化的类,它将从Hello
推断类型int,float
我以为我可以做这样的事情,但它不起作用:
template <template <typename A,typename B> class C>
class Check
{
void Foo(A,B,C)
{
// A is int .. B is float .. C is Hello
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Check<Hello> a;
}
我该怎么做?
编辑:
我想传递类Hello,并让模板推断其子类TemplatedClass使用的类型。
因此,当我创建一个类Check<Hello>
时,它将获得类型int和float
我真的无法更改TemplatedClass以包含typedefs(它来自外部.lib)
编辑:
我已将模板更改为使用Class,但我收到了以下错误:
错误C3200:"Hello":模板参数"C"的模板参数无效,应为类模板
首先,将typename
更改为class
,§14.1 [temp.param] p1
:
类型参数:
- class标识符opt
- 类标识符opt=类型id
- typename标识符opt
- typename标识符opt=类型id
- 模板<模板参数列表>class标识符opt
- 模板<模板参数列表>类标识符opt=id表达式
接下来,进行部分专业化:
template<class T>
class Check;
template< // not 'typename' vvvvv
template<typename,typename> class C,
typename A, typename B
>
struct Check<C<A,B> >{
// ...
};
但是,您仍然不能仅将Hello
传递给模板,因为即使Hello
派生自TemplatedClass
,也不允许对模板参数进行类型转换:
Check<Hello> c; // nope, 'Hello' is not a template
您可以将以下typedef添加到Hello
类中:
class Hello
: TemplatedClass<int,float>
{
public:
typedef TemplatedClass<int,float> base_type;
};
做:
检查c;//好啊但是Check
中的C
参数将是template TemplatedClass
,而不是Hello
。遗憾的是,没有办法直接做到这一点。一种解决方案是将派生类型作为额外的模板参数传递,或者将派生类型仅作为唯一的参数传递,并在内部进行类型提取:
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 <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);
或者,这个(还不清楚你的意图):
template <typename A,typename B>
class TemplatedClass {
typedef A TypeA;
typedef B TypeB;
};
template <typename C>
class Check
{
void Foo(typename C::TypeA& a, typename C::TypeB&) {}
}
// use:
Check<Hello<int,float> > 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
}
};
我认为你可以通过为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;
因此,TemplatedClass不需要更改,您可以将要放入Hello中的所有内容放入HelloBase中(使用模板作为简单携带类型的工具)。
在一般情况下,您想要的是不可能的-如果Hello
从TemplatedClass
派生两次呢?
然而,在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;
};
在C++03中,您仍然可以在方法内部获取参数,但不能在外部访问它们,除非插入特殊的typedef。
- C ++类型特征:确保子类实现方法
- 文本冒险游戏 - 如何区分一种项目类型与另一种项目类型以及如何构建项目类/子类
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- 附加类型安全的子类std::string
- 将方法参数类型更改为子类中的派生类
- 将子类实例保存在父类型变量中并通过父变量使用 Child 函数?
- 在子类上调用模板化静态方法时获取类的类型名
- 使用子类中的类型定义扩展模板类
- 当函数返回类型为父类时,如何返回子类的对象?
- 模型类/子类,其中子类类型在C++中先验未知
- C 模板继承.子类应用固定类型替换基类中的类型
- 可以将指向子类的指针分配给Varibale的超级类型
- 共享库中非模板基的模板子类导致未定义的符号类型信息'class'链接错误
- 在虚拟函数中使用子类类型参数
- C++子类类型的输出变量
- 如何返回“set”方法的子类类型
- 可以对返回子类类型的基类进行赋值操作符吗?
- 如何使子类上的操作符返回子类类型?
- 使用子类"类型转换"错误的 C++