根据另一个模板功能预先调用所有可能的模板功能

时间:2016-08-22 11:21:58

标签: c++ templates c++11

对于可能被调用的T中的每个f2<T>(),如何强制在某个函数f1<T>中调用所有f1_advanced()推进?

class Manager(){
    public: void f1_advanced (){ /* add code here */ }
    private: template<class T> void f1 (){  }
    public:  template<class T> void f2 (){  }
}


class Usage{
    void testCase(){
        Manager manager;
        manager.f1_advanced();
        //^^ Must call f1<A> and f1<B> automatically.
        //   Whether it calls f1<C> or not, both cases are ok for me.
        manager.f2<A>();
        manager.f2<B>();
        if(false) manager.f2<C>();
    }
}

注意:AB,...来自某个班级T0

我已搜索过,但找不到任何解决方案,不知道调用此功能的内容,甚至是否可行。

我只相信可以通过一些高级模板魔术来完成。

2 个答案:

答案 0 :(得分:2)

有两条规则:

  1. 使用静态const bool,由静态注册函数初始化。

  2. 所有游戏必须以字符书写

  3. 这是我的妖精游戏

    #include <unordered_map>
    #include <vector>
    #include <string>
    #include <typeindex>
    #include <iostream>
    
    //
    // base game object, suplpying polymorphic interface
    
    struct GameObject
    {
        virtual void identify_thyself() const = 0;
    
        GameObject() noexcept {}
        GameObject(GameObject&&) noexcept = default;
        GameObject(GameObject const&) noexcept = default;
        GameObject& operator=(GameObject&&) noexcept = default;
        GameObject& operator=(GameObject const&) noexcept = default;
        virtual ~GameObject() = default;
    };
    
    // every game should be written in character, or you're not doing it right
    
    template<class T>
    struct ye {};
    
    // an object manager which allows static registration of creation functions
    
    struct Manager
    {
        using game_object_ptr = std::unique_ptr<GameObject>;
        using create_object_function = std::function<game_object_ptr()>;
        struct static_data
        {
            std::unordered_map<
            std::type_index,
            create_object_function
            > creation_functions;
        };
    
        static static_data& get_static_data()
        {
            static static_data sd {};
            return sd;
        }
    
        template<class T>
        static void register_object(create_object_function creator) {
            auto& statics = get_static_data();
            // do whatever registration is required here
            statics.creation_functions.emplace(typeid(T), std::move(creator));
        }
    
        template<class T>
        static game_object_ptr create_monster(ye<T>)
        {
            // this will throw an exeption if the object wasn't registered
            return get_static_data().creation_functions.at(typeid(T))();
        }
    
    };
    
    // introducing: Ye Goblins!
    
    struct Goblin : GameObject
    {
        Goblin(std::string name)
        : _name(std::move(name))
        {}
    
        void identify_thyself() const override { std::cout << _name << " the goblin, waiting to a-slit your throat!\n"; }
        static const bool registered;
        std::string _name;
    };
    const bool Goblin::registered = [] {
        Manager::register_object<Goblin>([]()->Manager::game_object_ptr{
            static const std::vector<std::string> namez {
                "Grunt",
                "Basher",
                "Pulveriser",
                "Squisher"
            };
            static int iname = 0;
            auto next_name = [&] {
                auto s = namez[iname];
                ++iname;
                if (iname >= namez.size()) iname = 0;
                return s;
            };
    
            return std::make_unique<Goblin>(next_name());
        });
        return true;
    }();
    
    struct Hero : GameObject
    {
        void identify_thyself() const override { std::cout << "Harry the hero, waiting to degoblinise this blessed land!\n"; }
        static const bool registered;
    };
    
    const bool Hero::registered = [] {
        Manager::register_object<Hero>([]()->Manager::game_object_ptr{
            return std::make_unique<Hero>();
        });
        return true;
    }();
    
    struct appear_verb {};
    static constexpr appear_verb appear {};
    static constexpr appear_verb appears {};
    
    struct goblinator
    {
        auto operator,(appear_verb) const
        {
            std::vector<Manager::game_object_ptr> ye_hoard;
            std::generate_n(std::back_inserter(ye_hoard), 4,
                            [] { return Manager::create_monster(ye<Goblin>()); } );
            return ye_hoard;
        }
    };
    
    static constexpr goblinator a_number_of_merry_goblins {};
    
    struct heroinator
    {
        auto operator, (appear_verb) const
        {
            return Manager::create_monster(ye<Hero>());
        }
    };
    static constexpr heroinator our_hero {};
    
    struct identify_thyselfer
    {
        void operator, (const Manager::game_object_ptr& ptr) const {
            ptr->identify_thyself();
        }
    };
    static constexpr identify_thyselfer identify_thyself{};
    
    struct identify_thyselvser
    {
        void operator, (std::vector<Manager::game_object_ptr> const& them) const
        {
            for (auto& yeself : them)
            {
                yeself->identify_thyself();
            }
        }
    };
    static constexpr identify_thyselvser identify_thyselves{};
    
    struct methinkser
    {
        template<class T>
        decltype(auto) operator, (T const& musings) const
        {
            return std::cout << musings << '\n';
        }
    };
    static constexpr methinkser methinks {};
    
    
    int main()
    {
    //    Manager ye_manager; // not necessary since manager registration is static
    
    
        methinks, "Introducing, the Goblins:";
        auto ye_goblins = (a_number_of_merry_goblins, appear);
        identify_thyselves, ye_goblins ;
    
        methinks, "";
        methinks, "Introducing, the Hero:";
        auto ye_hero = (our_hero, appears);
        identify_thyself, ye_hero;
    }
    

    玩这款引人入胜的游戏时的输出示例:

    Introducing, the Goblins:
    Grunt the goblin, waiting to a-slit your throat!
    Basher the goblin, waiting to a-slit your throat!
    Pulveriser the goblin, waiting to a-slit your throat!
    Squisher the goblin, waiting to a-slit your throat!
    
    Introducing, the Hero:
    Harry the hero, waiting to degoblinise this blessed land!
    

答案 1 :(得分:0)

编译器无法知道Manager类的所有可能的类型扣除。你可以做的最好的事情就是编写一个包装器函数,该函数接收已经显式实例化的列表,并调用它们要测试的函数。