推断模板中的子类模板类型

问题描述

| 我有一个从模板类派生的类:
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更改为包含typedef(它来自外部.lib) 编辑: 我已将模板更改为使用Class,但出现此错误: 错误C3200:\'Hello \':模板参数\'C \'的无效模板参数,应为类模板     

解决方法

        首先,将
typename
更改为
class
§14.1 [temp.param] p1
:   类型参数:         类标识符   类标识符opt =类型ID   类型名称标识符   类型名称标识符opt =类型ID   template <模板参数列表>类标识符   template <模板参数列表>类标识符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 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,C)
    {
        // A is int .. B is float .. C is Hello
    }
};

...

Check<Hello> a;
因此,TemplatedClass不需要更改,您可以将要放入Hello中的所有内容都放入HelloBase中(使用模板作为简单携带类型的工具)。     ,        在一般情况下,您想要的是不可能的-如果两次从ѭ10衍生出
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;
};
在C ++ 03中,您仍然可以在方法内部获取参数,但是无法在外部访问它们,除非您插入特殊的typedef。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...