C++ C++;:我可以编写一个从T派生的模板类吗?

C++ C++;:我可以编写一个从T派生的模板类吗?,c++,templates,inheritance,base,derived,C++,Templates,Inheritance,Base,Derived,我不太清楚如何用英语表达这个词,但我想这样做: template <class T> class derived: public T { blah }; 模板 派生类:public T {blah}; 基本上,我有一个模板类,但我从模板中指定的类派生一个新类?也就是说,在编译时我不一定知道这个类 这可能吗如果是这样的话,其语义是什么? 例如,假设我正在尝试编写一个“父”类。在本例中,假设它是一个树父级。树的父类是树本身(因此它继承自树),但也有对子树的引用向量。然而,父类本身不一

我不太清楚如何用英语表达这个词,但我想这样做:

template <class T>
class derived: public T
{ blah };
模板
派生类:public T
{blah};
基本上,我有一个模板类,但我从模板中指定的类派生一个新类?也就是说,在编译时我不一定知道这个类

这可能吗
如果是这样的话,其语义是什么?

例如,假设我正在尝试编写一个“父”类。在本例中,假设它是一个树父级。树的父类是树本身(因此它继承自树),但也有对子树的引用向量。
然而,父类本身不一定是树;它可以是任何类,因此我可以编写如下内容:

Parent<tree> treeParent;
Parent<shrub> shrubParent;
父树型;
亲本灌木亲本;

是。这是可能的。试试看

在编译时我不一定知道这个类

我想,您的意思是“在定义类模板时,我不一定知道类。”


在编译时,您已经定义了类模板,并在代码中使用它,将模板参数传递给它,这意味着您在编译时就知道了类(即模板参数)。如果您不知道要用作
基的类,那么您甚至无法编译代码。

是。这是可能的。试试看

在编译时我不一定知道这个类

我想,您的意思是“在定义类模板时,我不一定知道类。”


在编译时,您已经定义了类模板,并在代码中使用它,将模板参数传递给它,这意味着您在编译时就知道了类(即模板参数)。如果您不知道要用作
基的类,那么您甚至无法编译代码。

是的,这是可能的。这与类模板中模板参数的任何其他用法的语义没有区别。您可以有一个类型为T的成员,一个类型为T的函数参数,也可以将T作为基类。这并不特别。

是的,这是可能的。这与类模板中模板参数的任何其他用法的语义没有区别。您可以有一个类型为T的成员,一个类型为T的函数参数,也可以将T作为基类。这并不特别。

这确实是可能的,通常用于:

就像这个令人难以置信的精心设计的例子:

template<typename OutputPolicy>
struct Writer : public OutputPolicy {
  using OutputPolicy::print;
  void write(const std::string&) {
    //do some formatting etc.
    print(string);
  }
};

class StdoutPolicy {
public:
  set_linebreaks(const std::string&);
protected:
  void print(const std::string&);
};
模板
结构编写器:公共输出策略{
使用OutputPolicy::print;
无效写入(常量std::string&){
//做一些格式化等。
打印(字符串);
}
};
类StdoutPolicy{
公众:
设置换行符(常量std::string&);
受保护的:
无效打印(const std::string&);
};

可通过
Writer
访问策略中的公共方法。这样,策略就可以用其他方法装饰它所使用的类。

这确实是可能的,并且通常用于:

就像这个令人难以置信的精心设计的例子:

template<typename OutputPolicy>
struct Writer : public OutputPolicy {
  using OutputPolicy::print;
  void write(const std::string&) {
    //do some formatting etc.
    print(string);
  }
};

class StdoutPolicy {
public:
  set_linebreaks(const std::string&);
protected:
  void print(const std::string&);
};
模板
结构编写器:公共输出策略{
使用OutputPolicy::print;
无效写入(常量std::string&){
//做一些格式化等。
打印(字符串);
}
};
类StdoutPolicy{
公众:
设置换行符(常量std::string&);
受保护的:
无效打印(const std::string&);
};
可通过
Writer
访问策略中的公共方法。这样,策略就可以用其他方法装饰它所使用的类。

如下所示:

#include <iostream>
using namespace std;

template<typename T>class classTemplateBase
{
    public:
       T value;
       classTemplateBase(T i)
       {
          this->value = i;
       }
       void test()
       {
          cout << value << endl;
       }
};

class classTemplateChild : public classTemplateBase<char>
{
    public:
       classTemplateChild( ): classTemplateBase<char>( 0 )  // default char is NUL
       {
          ;
       }

       classTemplateChild(char c): classTemplateBase<char>( c )
       {
          ;
       }
       void test2()
       {
          test();
       }
};

int main()
 {
      classTemplateBase <int> a( 42 );
      classTemplateChild b( 'A' );

      a.test();   // should print "42"
      b.test();   // should print "A"
      b.test2();  // should print "A"

  return 0;
 }
#包括
使用名称空间std;
templateclass类TemplateBase
{
公众:
T值;
classTemplateBase(TI)
{
这个->值=i;
}
无效测试()
{
不能像这样:

#include <iostream>
using namespace std;

template<typename T>class classTemplateBase
{
    public:
       T value;
       classTemplateBase(T i)
       {
          this->value = i;
       }
       void test()
       {
          cout << value << endl;
       }
};

class classTemplateChild : public classTemplateBase<char>
{
    public:
       classTemplateChild( ): classTemplateBase<char>( 0 )  // default char is NUL
       {
          ;
       }

       classTemplateChild(char c): classTemplateBase<char>( c )
       {
          ;
       }
       void test2()
       {
          test();
       }
};

int main()
 {
      classTemplateBase <int> a( 42 );
      classTemplateChild b( 'A' );

      a.test();   // should print "42"
      b.test();   // should print "A"
      b.test2();  // should print "A"

  return 0;
 }
#包括
使用名称空间std;
templateclass类TemplateBase
{
公众:
T值;
classTemplateBase(TI)
{
这个->值=i;
}
无效测试()
{

cout这是可能的,它也很常见,并且有自己的名字:奇怪的循环模板模式。请看。

这是可能的,它也很常见,并且有自己的名字:奇怪的循环模板模式。请看。

谢谢!我在课间休息一段时间,在学校的一个校友会上问这个问题计算机,所以我没有机会编译我所想的。@TragicPixel:试着编译。你也可以使用
www.ideone.com
。这是一个在线编译器。谢谢!我在课间花点时间在学校的电脑上问这个问题,所以我没有机会编译我所想的。@TragicPixel:试着编译。你也可以使用
www.ideone.com
。这是一个在线编译器。也许你应该在发布前试用一下?我在一台没有编译器的计算机上,或者至少,我没有太多时间在上面尝试和查找。纳瓦兹好心地将我指给一个在线IDE。你甚至可以更进一步,定义一个类
派生:Base
,因此,该类继承自一个了解派生类的基类:)也许你应该在发布之前尝试一下?我在一台没有编译器的计算机上,或者至少,我没有太多时间在上面尝试和查找编译器。纳瓦兹好心地将我指给一个在线IDE。你甚至可以更进一步,定义一个类
Derived:Base
,因此该类继承自一个了解派生类的基类:)+1,用于指出它是一种基于策略的设计。@Nawaz如果您手头有一个全面的实际示例,请将其添加到答案中。否则,我将稍后尝试查找。+1用于指出它是一种基于策略的设计。@Nawaz如果你手头有一个全面的现实世界的例子,请将它添加到答案中