我正在尝试为一个自由函数 listenTo(SomeAnimal)
提供一个接口(interface)描述,该函数应该对满足特定类型要求的类型进行操作(它应该是一种动物)。函数参数不应使用纯虚方法的接口(interface)继承机制。
我破解了一个解决方案,其中自由函数通过基类的 sfinae 语句检查参数类型。为了保证参数实现基类的接口(interface),我使用 = 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;
}
最佳答案
C++ 还没有 Concepts :-( 但 gcc-6 实现了它:
template <class T>
concept bool Animal() {
return requires(const T& a) {
{a.sound()} -> std::string;
};
}
void listenTo(const Animal& animal) {
std::cout << animal.sound() << std::endl;
}
但是您可以使用 is-detected
相对轻松地创建特征:
typename <typename T>
using sound_type = decltype(std::declval<const T&>().sound());
template <typename T>
using has_sound = is_detected<sound_type, T>;
template <typename T>
using is_animal = has_sound<T>;
// or std::conditional_t<has_sound<T>::value /*&& other_conditions*/,
// std::true_type, std::false_type>;
然后是常规的 SFINAE:
template<class T>
std::enable_if_t<is_animal<T>::value>
listenTo(const T& animal) {
std::cout << animal.sound() << std::endl;
}
关于c++ - 使用=delete 进行接口(interface)描述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39622051/