У меня есть класс, подобный следующему:
class SomeClass
{
public:
template<typename... Args>
void doSomething(Args && ... args);
//... other methods etc.
};
Однако, что я действительно хочу, так это иметь два разных типа SomeClass
.В идеале я мог бы получить из общего интерфейса SomeOtherClass
, но мне нужно иметь другую реализацию doSomething
, и шаблонные методы не могут быть виртуальными.Я мог бы создать шаблонный класс, но тогда каждый метод, который принимает один из них (а их много), сам должен быть шаблоном и т. Д.
Лучшее, что я смог придумать, - это реализоватьоба типа doSomething
в базовом классе и этот метод вызывают виртуальный метод, чтобы определить, какой использовать во время выполнения.
Есть ли лучшее решение?
Дальнейшее объяснение
У меня есть много методов, которые выглядят примерно так:
void foo(SomeClass * obj);
foo
вызывает obj->doSomething
, и все это прекрасно работает, однако с тех пор я понял, что мне нужен другой тип SomeClass
но хотите, чтобы он работал с этими же методами, например:
class SomeClass
{
public:
// This won't work
template<typename... Args>
virtual void doSomething(Args && ... args) = 0;
// ... other common methods
};
class TheFirstType
{
public:
template<typename... Args>
void doSomething(Args && ... args);
// ... other specific methods
};
class TheSecondType
{
public:
template<typename... Args>
void doSomething(Args && ... args);
// ... other specific methods
};
Выше было бы идеально, если бы это было законно, но виртуальные методы не могли быть шаблонизированы.До сих пор я обходил это ограничение, определяя только doSomething
в базовом классе, но с реализацией для TheFirstType
и TheSecondType
, отделенными оператором if, который проверяет, какой тип на самом деле является экземпляром:
template<typename... Args>
void SomeClass::doSomething(Args && ... args)
{
if (this->type() == FIRST_TYPE) {
// ... the implementation that should rightfully be part of TheFirstType
} else if (this->type() == SECOND_TYPE) {
// ... the implementation that should be part of TheSecondType
}
}
Это кажется грязным, поэтому мне было интересно, есть ли лучший способ.