【问题标题】:error: templates may not be 'virtual'错误:模板可能不是“虚拟的”
【发布时间】:2015-01-18 12:07:36
【问题描述】:

我希望能够为基类 MCFormater 提供一种适用于不同类型(uint32、uint8...)的格式化方法

class MCFormater {
    public:
    MCFormater() {}
    virtual ~MCFormater() {}
    virtual mcc_t Gen();
protected:
    template<typename K>                          //here is the problem
    virtual void Format(K& a, const K& b) = 0; 
    //...
    uint32_t a;
    uint8_t b;
    void Foo();
};

void MCFormater::Foo() {
   Format<uint32_t>(a, 3);     //I want to be able to call for Format
   Format<uint8_t>(b, 3);      //with uint32_t, and uint8_t, and more 
}


class GFormater : public MCFormater {
    GFormater() {}
    template<typename K>
    virtual void Format(K& a, const K& b) {
        a = b;
    }
};

class EFormater : public MCFormater {
    EFormater() {} 
    template<typename K>
    virtual void Format(K& a, const K& b) {
        a |= b;
    }
};

但我收到错误:模板可能不是“虚拟的”。 什么是正确的方法? (有吗?)

【问题讨论】:

    标签: c++


    【解决方案1】:

    修改...

    class MCFormater {
        public:
        MCFormater() {}
        virtual ~MCFormater() {}
        virtual mcc_t Gen();
    protected:
        template<typename K>                          //here is the problem
        virtual void Format(K& a, const K& b) = 0; 
        //...
        uint32_t a;
        uint8_t b;
        void Foo();
    };
    
    void MCFormater::Foo() {
       Format<uint32_t>(a, 3);
       Format<uint8_t>(b, 3);
    }
    
    
    class GFormater : public MCFormater {
        GFormater() {}
        template<typename K>
        virtual void Format(K& a, const K& b) {
            a = b;
        }
    };
    
    class EFormater : public MCFormater {
        EFormater(FTEKeeps* keeps) : MCFormater(keeps) {} 
        template<typename K>
        virtual void Format(K& a, const K& b) {
            a |= b;
        }
    };
    

    到...

    #include<iostream>
    
    using namespace std;
    
    template<typename K>
    class MCFormater {
    public:
        MCFormater() {}
        virtual ~MCFormater() {}
        virtual mcc_t Gen();
    protected:  
        virtual void Format(K& a, const K& b) = 0;
        //...
        uint32_t a;
        uint8_t b;
        void Foo();
    };
    
    template<typename K>
    void MCFormater<K>::Foo() {
        Format<uint32_t>(a, 3);
        Format<uint8_t>(b, 3);
    }
    
    template<typename K>
    class GFormater : public MCFormater<K> {
        GFormater() {}  
        virtual void Format(K& a, const K& b) {
            a = b;
        }
    };
    
    template<typename K>
    class EFormater : public MCFormater<K> {
        EFormater(FTEKeeps* keeps) : MCFormater<K>(keeps) {}    
        virtual void Format(K& a, const K& b) {
            a |= b;
        }
    };
    

    说明:成员函数模板不能是虚拟的。如果允许这样做,那么每次使用不同类型调用 Format 函数时,链接器都必须向虚拟表添加一个新条目。动态链接会非常复杂。

    【讨论】:

    • 我不能从基类外部强制类型 K,因为基类内部的 K 不同
    • "Member functions cannot be virtual" , template 属于该句的开头。值得注意的是,模板类成员 can 是虚拟的,但不是模板成员 functions (您的代码显示,但在解释中未提及)。跨度>
    • @Todder 那么你有一个设计问题。您不能拥有虚拟模板成员函数。如果必须,提供重载或接受您的对象作为其参数之一的非成员模板函数。
    • 你不能解释一下你做了什么改变吗?从心理上区分这堵代码墙并不容易。
    • 我不认为代码的Before和After版本之间的差异很难看出。如果提出问题的人希望我进一步解释,我很乐意。
    猜你喜欢
    • 2011-06-25
    • 2018-06-18
    • 2023-04-10
    • 2015-01-04
    • 2011-01-22
    • 2012-10-08
    相关资源
    最近更新 更多