C++ 调用超级模板类方法而不知道C++;
我有一个使用template的基类,它有一些不依赖于模板类型的方法,但是当我使用指针C++ 调用超级模板类方法而不知道C++;,c++,templates,C++,Templates,我有一个使用template的基类,它有一些不依赖于模板类型的方法,但是当我使用指针base*a而不是派生类时,编译器会抱怨,因为没有指定类型。我知道在java中这是可能的,但不确定C++是否可能。这里有一个简单的例子: template <typename T> class Base { public: Base(const T& t) : _t(t) {} virtual ~Base() { } void doSomething() { std:
base*a
而不是派生类时,编译器会抱怨,因为没有指定类型。我知道在java中这是可能的,但不确定C++是否可能。这里有一个简单的例子:
template <typename T>
class Base {
public:
Base(const T& t) : _t(t) {}
virtual ~Base() { }
void doSomething() { std::cout << "Hello world/n"; }
virtual T getVal() const { return _t; }
private:
T _t;
};
class DerivedA : public virtual Base<std::string>
{
public:
DerivedA(const std::string& path) : Base<std::string>(path) {}
virtual ~DerivedA() {}
};
class DerivedB : public virtual Base<int>
{
public:
DerivedB(int value) : Base<int>(value) {}
virtual ~DerivedB() {}
};
int main(int argc, const char * argv[]) {
DerivedA d("hello world\n");
Base* basePtr = &d; // ERROR: Use of class template 'Base' requires template arguments
basePtr->doSomething();
模板
阶级基础{
公众:
基本(常数T&T):\u T(T){}
虚拟~Base(){}
void doSomething(){std::cout doSomething();
提前感谢只需创建另一个非模板的基类:
class ReallyBase {
public:
virtual ~ReallyBase() = default;
void doSomething() { std::cout << "Hello world\n"; }
};
template <typename T>
class Base : public ReallyBase {
public:
Base(const T& t) : _t(t) {}
virtual const T& getVal() const { return _t; }
private:
T _t;
};
类ReallyBase{
公众:
virtual~ReallyBase()=默认值;
void doSomething(){std::cout只需创建另一个不是模板的基类:
class ReallyBase {
public:
virtual ~ReallyBase() = default;
void doSomething() { std::cout << "Hello world\n"; }
};
template <typename T>
class Base : public ReallyBase {
public:
Base(const T& t) : _t(t) {}
virtual const T& getVal() const { return _t; }
private:
T _t;
};
类ReallyBase{
公众:
virtual~ReallyBase()=默认值;
java中的CUT:P>>泛型与C++中的模板完全不同。泛型是基于类型擦除的,而模板则是每个实例都是完全不同于不同实例化的分离类型。
Ie在Java中,ArrayList
与ArrayList
基本相同。另一方面,对于模板,Base
与Base
没有关系(不同于由同一模板生成的两种类型),因此派生类实际上不共享公共基类
为了解决您的问题,您可以编写一个(非模板)基类声明所有派生类的公共接口。java中的 泛型与C++中的模板完全不同。泛型基于类型擦除,而模板则每个实例化是完全不同于不同实例化的分离类型。
Ie在Java中,ArrayList
与ArrayList
基本相同。另一方面,对于模板,Base
与Base
没有关系(不同于由同一模板生成的两种类型),因此派生类实际上不共享公共基类
要解决您的问题,您可以编写一个(非模板)基类来声明所有派生类的公共接口。让我们先来谈谈解决问题的简单方法,编写派生函数:
template<typename T>
Base<T>* make_base(Base<T>* param) {
return param;
}
此解决方案可以进一步改进,如中所示,但由于我认为这不是最佳解决方案,因此我不会将答案与之混淆,而是将此类优化留给您仔细阅读
但是2nd让我们谈谈如何改进您的设计。您会注意到,任何标准容器都会使用value\u type=
创建一个,从而存储它们传递的模板类型。这对于这种情况非常重要!如果您公开将using value\u type=T
添加到基模板中课堂上,您将绕过所有问题,无需make_base
即可:
Base<decltype(d)::value_type>* basePtr = &d;
让我们先来谈谈解决问题的简单方法,写一个派生函数:
template<typename T>
Base<T>* make_base(Base<T>* param) {
return param;
}
此解决方案可以进一步改进,如中所示,但由于我认为这不是最佳解决方案,因此我不会将答案与之混淆,而是将此类优化留给您仔细阅读
但是2nd让我们谈谈如何改进您的设计。您会注意到,任何标准容器都会使用value\u type=
创建一个,从而存储它们传递的模板类型。这对于这种情况非常重要!如果您公开将using value\u type=T
添加到基模板中课堂上,您将绕过所有问题,无需make_base
即可:
Base<decltype(d)::value_type>* basePtr = &d;
如果您的函数不依赖于其签名中的任何模板参数,如doSomething
函数,则可以创建非模板“real”“模板>代码> BASE//Cux>类继承。你不能这样做。<代码> BASE< /COD>和 BASE<代码>是不同的专业,所以它们是不同的类型。你不能把苹果丢进汽车……不要把java泛型与C++模板混淆,这是两个非常不同的概念。建议使用一个具体的。(非模板)基类通常是正确的,但值得检查-为什么需要基类指针?您使用它的目的是什么?如果您有不依赖其签名中任何模板参数的函数,如doSomething
函数,则可以创建非模板“real”“模板>代码> BASE//Cux>类继承。你不能这样做。<代码> BASE< /COD>和 BASE<代码>是不同的专业,所以它们是不同的类型。你不能把苹果丢进汽车……不要把java泛型与C++模板混淆,这是两个非常不同的概念。建议使用一个具体的。(非模板)基类通常是正确的,但值得检查-为什么需要基类指针?您使用它的目的是什么?我怀疑ReallyBase::doSomething
应该在这里仍然是公开的,并且ReallyBase
可能也应该有一个虚拟dtor。@无用:谢谢您没有遵守您的名字。我怀疑ReallyBase::doSomething
在这里应该仍然是公开的,而且ReallyBase
可能也应该有一个虚拟的dtor。@无用:谢谢你没有做到你的名字。