Я пытаюсь предоставить описание интерфейса для бесплатной функции listenTo(SomeAnimal)
, которая должна работать с типами, которые отвечают определенным требованиям типа (это должно быть животное). Аргументы функции не должны использовать механизм наследования интерфейса с помощью виртуальных методов.Использование = delete для описания интерфейса
Я взломал решение, в котором свободная функция проверяет тип аргумента с помощью инструкции sfinae для базового класса. Чтобы гарантировать, что аргумент реализует интерфейс базового класса, я удалил методы базового класса, используя = delete
. Я не нашел подобного решения в Интернете, поэтому я не уверен, имеет ли он смысл, но он работает.
Вот он, любые мнения?
#include <iostream>
#include <type_traits>
class IAnimal {
public:
// Interface that needs to be implemented
std::string sound() const = delete;
protected:
IAnimal(){}
};
class Cat : public IAnimal {
public:
// Implements deleted method
std::string sound() const {
return std::string("Meow");
}
};
class WildCat : public Cat {
public:
// Overwrites Cat sound method
std::string sound() const {
return std::string("Rarr");
}
};
class Dog : public IAnimal{
public:
// Implements deleted method
std::string sound() const {
return std::string("Wuff");
}
};
class Car {
public:
// Implements deleted method
std::string sound() const {
return std::string("Brum");
}
};
// Sfinae tests for proper inheritance
template<class TAnimal,
typename = std::enable_if_t<std::is_base_of<IAnimal, TAnimal>::value> >
void listenTo(TAnimal const & a) {
std::cout << a.sound() << std::endl;
}
int main(){
// Objects of type IAnimal can not be instanciated
// IAnimal a;
// Cats and Dogs behave like IAnimals
Cat cat;
WildCat wildCat;
Dog dog;
Car car;
listenTo(cat);
listenTo(wildCat);
listenTo(dog);
// A car is no animal -> compile time error
// listenTo(car);
return 0;
}
Вы всегда можете опустить определение (вместо '= удаление;') – Rakete1111
Да, можно, но тогда вы получите не так хороший 'неопределенная ссылка в' ошибка в компиляторе (в случае игнорирования интерфейса). – erikzenker
Я думаю, что в книге Струустапа (C++ Programming Language 2013) он описывает этот подход с аналогичным примером. Мне это хорошо, но я вряд ли способен оценить его. – Aganju