Ошибка: шаблоны не могут быть "виртуальными"

Я хотел бы иметь возможность предоставить базовому классу 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;
    }
};

но я получаю ошибку: шаблоны не могут быть "виртуальными". Как правильно это сделать? (есть один?)

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 другого типа. Динамическое связывание было бы неприемлемо сложным.

Другие вопросы по тегам