其他分享
首页 > 其他分享> > c – 使用= delete进行接口描述

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;
}

Demo

但是你可以用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