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++;_C++_Templates - Fatal编程技术网

C++ 调用超级模板类方法而不知道C++;

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:

我有一个使用template的基类,它有一些不依赖于模板类型的方法,但是当我使用指针
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。@无用:谢谢你没有做到你的名字。