繁体   English   中英

C ++:使用类型名作为基础的模板类中的函数调用编译时错误

[英]C++ : Function call Compile-Time Error from a Template Class using Typename as Base

我不知道,也找不到概念名称来简化我的问题(标题也是如此)。 所以我发布了整个代码。 下面是具有两个基类的代码。 然后使用类模板创建一个派生类。 派生类使用类型名T继承两个基类。每个基类都具有称为foo()和boo()的唯一函数。

我的问题是:
1)在这种情况下,是否可以在派生类中同时使用两个函数调用(在callMethods()中)? 我遇到错误,不知道要解决它。
2)如果现有设计错误,还是需要更改类设计?
3)如果设计正确,设计这样的班级是一种好习惯吗?

错误信息:

error: 'boo' is not a member of 'mybase_1'
         T::boo();     
error: 'foo' is not a member of 'mybase_2'
         T::foo();      
                ^                ^

测试代码:

enum class myenum : int {one, two};

class mybase_1{
protected:
    void foo(){
        qDebug() << "foo called\n";
    }
};

class mybase_2{
protected:
    void boo(){
        qDebug() << "boo called\n";
    }
};

template <typename T>
class myderived : public T{
public:
    myderived(myenum _enm);
    void callMethods();
private:
    myenum enm;
};

template <typename T> myderived<T>::myderived(myenum _enm):enm{_enm}{
    qDebug() << "derived constructor\n";
}
template <typename T> void myderived<T>::callMethods(){
    switch(enm){
    case myenum::one:
        T::foo();
        break;
    case myenum::two:
        T::boo();
        break;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    myderived<mybase_1> tmp1(myenum::one);
    tmp1.callMethods();
    myderived<mybase_2> tmp2(myenum::two);
    tmp2.callMethods();

    return a.exec();
}

1)在这种情况下,是否可以在派生类中同时使用两个函数调用?

在您的实现中,仅当派生类或基类实现这两个函数时。

我遇到错误,不知道要解决它。

该类型在编译时是已知的,因此最简单的解决方案是专门化模板:

template<>
void myderived<mybase_1>::callMethods(){
    foo();
}
template<>
void myderived<mybase_2>::callMethods(){
    boo();
}

如果您不需要枚举,则可以将其与switch语句一起丢弃。

1)只是为了纠正您的错误-您的开关盒是

switch(enm){
case myenum::one:
    T::foo();
    break;
case myenum::two:
    T::boo();
    break;
}

假设T同时具有foo()和boo()。 在两个基类中定义这两个函数(它们是否为空无关紧要。)

我猜您想做的是从派生类型调用base函数,我猜是继承已创建。

enum class myenum : int {one, two};

class mybase_1{
protected:
    void foo(){
        qDebug() << "foo in mybase_1 is called \n";
    }
};

class mybase_2{
protected:
    void foo(){
        qDebug() << "foo in mybase_2 is called\n";
    }
};

template <typename T>
class myderived : public T{
public:
    myderived(myenum _enm);
    void callMethods();
private:
    myenum enm;
};

template <typename T> myderived<T>::myderived(myenum _enm):enm{_enm}{
    qDebug() << "derived constructor\n";
}
template <typename T> void myderived<T>::callMethods(){
    foo(); // the foo called depends on the parameter supplied to template, which determines from which class your derived class has been derived.
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    myderived<mybase_1> tmp1(myenum::one);
    tmp1.callMethods();
    myderived<mybase_2> tmp2(myenum::two);
    tmp2.callMethods();

    return a.exec();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM