模板类中的静态模板函数

时间:2017-05-12 07:22:35

标签: c++ templates

这里我们有两个模板类。

第一个名为" Factory",它是单例工厂模型类,并且有一个模板成员函数,负责在这个工厂中注册类生产者。

第二个名为" FactoryRegister",它唯一的职责是在T1工厂注册T2。

最后,我们有一个声明FactoryRegister变量的宏,通过在全局范围内使用这个宏,我们意识到在程序运行之前注册工厂中的所有类。

#include <memory>
#include <mutex>
#include <map>
#include <string>

template <typename Base>
class Factory {
public:

    static std::shared_ptr<Factory<Base> > get_instance() {
        static std::shared_ptr<Factory> factory;
        if (!factory) {
            static std::mutex _new_mutex;
            std::lock_guard<std::mutex> guard(_new_mutex);
            if (!factory) {
                factory.reset(new Factory);
            }
        }

        return factory;
    }

    template <typename Derived,
              typename = typename std::enable_if<std::is_base_of<Base, Derived>::value>::type>
    void add(std::string pname) {
        std::lock_guard<std::mutex> guard(_mutex);
        _producers.emplace(pname, [](std::string name) {return new Derived(name);});
    }

    void del(std::string pname) {
        std::lock_guard<std::mutex> guard(_mutex);
        _producers.erase(pname);
    }

    bool is_exist(std::string pname) {
        return _producers.find(pname) != _producers.end();
    }

    std::shared_ptr<Base> create(std::string pname, std::string name) {
        std::shared_ptr<Base> ret;
        if (is_exist(pname)) {
            ret.reset(_producers[pname](name));
        }
        return ret;
    }

private:
    Factory() = default;

    Factory(const Factory&) = delete;

    Factory& operator=(Factory&) = delete;

private:
    std::mutex _mutex;
    std::map<std::string, std::function<Base*(std::string)> > _producers;
};

template<typename T1, typename T2>
struct FactoryRegister {
    FactoryRegister(std::string name) {
        Factory<T1>::get_instance()->add<T2>(name);
    }
};

#define REGISTER_TO_FACTORY(BaseClass, DerivedClass) \
    const FactoryRegister<BaseClass, DerivedClass> \
    REGISTER_WITH_##BaseClass_##DerivedClass(#DerivedClass)

使用代码,编译器(gcc4.8.2)显示如下:

factory.h: In constructor 'FactoryRegister<T1, T2>::FactoryRegister(std::string)':
factory.h:62:44: error: expected primary-expression before '>' token
         Factory<T1>::get_instance()->add<T2>(name);

任何人都能说出原因吗?

1 个答案:

答案 0 :(得分:0)

来自C ++&#39; 03标准14.2 / 4:

  

当成员模板专业化的名称出现之后。要么    - &GT;在postfix-expression中,或在qualified-id中的nested-name-specifier之后,以及postfix-expression或qualified-id   取决于模板参数(14.6.2),成员模板名称   必须以关键字模板为前缀。否则名称是   假设命名为非模板。

Factory<T1>::get_instance()-> template add<T2>(name);

顺便说一句,有些编译器具有允许编译原始代码而没有错误的特殊模式