Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 推断模板中的子类模板类型_C++_Templates_Inheritance - Fatal编程技术网

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>和类< /C>在模板中使用时,C++是相同的。将一个更改为另一个是没有意义的。@DeadMG:不,对于模板参数来说,这很重要。您有3个模板参数。。。只通过1(T_Base_type)@Yochai:Woops,忘记了第二部分的部分专门化,谢谢。@DeadMG:§14.1[temp.param]p1:“类型参数:…模板<模板参数列表>类标识符(op)”。
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;
};