c – 使用= delete进行接口描述
作者:互联网
我试图为自由函数listenTo(SomeAnimal)提供一个接口描述,该函数应该在满足特定类型要求的类型上运行(它应该是动物).函数参数不应该使用纯虚方法的接口继承机制.
我破解了一个解决方案,其中free函数通过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;
}
解决方法:
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,c11,sfinae 来源: https://codeday.me/bug/20190828/1756041.html