Указание типа шаблона метода базового класса (c ++) - PullRequest
1 голос
/ 14 апреля 2020

Я пытаюсь создать класс, используя диспетчеризацию тегов для разных реализаций методов, для разных случаев использования.

В классе есть методы шаблонов, использующие теги со специализацией шаблонов для различных вариантов поведения с одинаковой сигнатурой метода.


Пользовательский сценарий ios:

  1. Я хочу, чтобы один пользователь мог устанавливать тег при объявлении объекта и больше не заботиться о теге при последующем использовании его методы.
  2. Я также хочу, чтобы другой пользователь использовал теги более динамично, например, использовал разные теги в разных частях кода (с одним и тем же объектом).

Возможно, это так желаемое за действительное, что один класс мог бы сделать и то, и другое без операторов if или других накладных расходов? Поэтому я попытался использовать два класса с одинаковыми именами, которые можно использовать для этих двух сценариев ios.

Я сейчас пытаюсь получить подкласс шаблона (используется для сценария 1) для наследования от базового класса (используется для сценария 2) со всеми членами и методами, но также установите типы шаблонов методов (теги). Минимальный пример того, что я пытаюсь описать, показан ниже (без диспетчеризации тегов).


Есть ли способ установить тип шаблона шаблона метода базового класса без написания метод обертки? Например, с использованием using (все же получилось, см. ниже).


Идеальное решение также будет использовать одинаковое имя типа для шаблона (подкласса) и не шаблонный (базовый) класс, но я думаю, что это не разрешено в том же пространстве имен? Этот вопрос является второстепенным по отношению к вышеуказанному.


Определения классов

// Base class declaration
class tA;

// Template specialization implementation
namespace detail
{
    template<typename T>
    void doSomethingImpl(const tA& a)
    {
        std::cout << "Does something default." << std::endl;
    }

    template<>
    void doSomethingImpl<int>(const tA& a)
    {
        std::cout << "Does something int'y" << std::endl;
    }

    template<>
    void doSomethingImpl<float>(const tA& a)
    {
        std::cout << "Does something float'y" << std::endl;
    }
}

// Base class definition
class tA
{
  public:    
    template<typename T>
    void doSomething() 
    {
        detail::doSomethingImpl<T>(*this);
    }
};


// Subclass, should set doSomething type in object declaration
template<typename T>
class tB : public tA
{
  public:
    // using tA::doSomething<T>; // error: a template-id may not appear in a using-declaration
                                 // What do do? I'd rather not use a wrapped method below.

    // Unwanted wrapper method
    void doSomething()
    {
        tA::doSomething<T>();
    }
};

Использование

int main()
{
    std::cout << "Dynamic usage:" << std::endl;

    tA dynamicUsage{};
    dynamicUsage.doSomething<bool>();  // "Does something default"
    dynamicUsage.doSomething<int>();   // "Does something int'y"
    dynamicUsage.doSomething<float>(); // "Does something float'y"

    std::cout << "\nStatic usage:" << std::endl;

    tB<int> staticUsage{};
    staticUsage.doSomething();         // "Does something int'y"

    staticUsage.tA::doSomething<float>(); // This also works due to public inhertiance.
}
...