ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 使用= delete进行接口描述

2019-08-28 22:18:53  阅读:242  来源: 互联网

标签:c c11 sfinae


我试图为自由函数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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有