Loki多种方法是否成为C 1​​1?

我正在阅读Andrei Alexandrescu的 Modern C++ Design Generic Programming and Design Patterns Applied和关于多方法的第11章正好解决了我想要解决的问题.本书的所有源代码都发布在名为 Loki的库中.

问题在于该书相当陈旧(2001)并处理了在C 11中不再适用的限制(例如,模板参数的数量不能变化).我试着查看Loki是否已经使用C 11进行了重写,但是最后一次修改是在2009年,并且在Andrei Alexandrescu’s home page没有更新.但是,在做了一些研究之后我觉得Loki就像它在某种意义上就像Boost一样被纳入标准库.

C 11中是否采用了多方法成语或部分内容

解决方法

它不在标准中,但使用由一对typeid索引的函数对象的映射构建起来相当容易.

为了完整起见,这是我的第一次尝试:

#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <map>
#include <functional>
#include <memory>

struct Animal {
    virtual std::type_index type() const = 0;
};

template <class T> struct AnimalImpl : public Animal {
    std::type_index type() const override {
        return typeid(T);
    }
};

struct Dog : AnimalImpl<Dog> {

};

struct Cat : AnimalImpl<Cat> {

};

struct Mouse : AnimalImpl<Mouse> {

};

using Types = std::tuple<std::type_index,std::type_index>;
using Outcome = std::function<void (Animal&,Animal&)>;
using dispatchMap = std::map<Types,Outcome>;

using namespace std;


void catVDog(Animal& cat,Animal& dog) {
    cout << "dog wins\n";
}

void catVMouse(Animal& cat,Animal& mouse)
{
    cout << "cat wins\n";
}

dispatchMap makeOutcomes()
{
    dispatchMap result;
    result.emplace( make_pair( Types {typeid(Cat),typeid(Dog)},catVDog) );
    result.emplace( make_pair( Types {typeid(Dog),typeid(Cat)},[](Animal&a1,Animal&a2) { return catVDog(a2,a1); }) );

    result.emplace( make_pair( Types {typeid(Cat),typeid(Mouse)},catVMouse) );
    result.emplace( make_pair( Types {typeid(Mouse),Animal&a2) { return catVMouse(a2,a1); }) );
    return result;
}

const dispatchMap outcomes = makeOutcomes();

void fight(Animal& a1,Animal& a2)
{
    auto it = outcomes.find(Types{ a1.type(),a2.type() });
    if (it == outcomes.end()) {
        cout << typeid(a1).name() << " " << typeid(a2).name() << " ";
        std::cout << "no fight\n";
    }
    else {
        it->second(a1,a2);
    }
}


int main()
{
    unique_ptr<Animal> cat { new Cat {} };
    unique_ptr<Animal> dog { new Dog {} };
    unique_ptr<Animal> mouse { new Mouse {} };

    fight(*cat,*dog);
    fight(*cat,*mouse);
    fight(*dog,*cat);
    fight(*dog,*mouse);

   return 0;
}

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...