省略模板参数(用于函数指针参数)

时间:2016-02-02 11:20:35

标签: c++ templates template-specialization member-function-pointers function-signature

我正在编写存储函数指针以创建用户对象的模板工厂 我想支持带有和不带参数的用户创建函数(现在,将使用一个或零个参数)。 (不幸的是,我不能使用boost或c11)

template< typename T, typename K, typename D >
//T (Type) is a polymorphic type
//K (Key) should have operator < and be copyable
//D (Data argument for creator function) can be copyable
class Factory
{
public:
    typedef std::tr1::shared_ptr<T> shared_ptr;
    //auto gen Ctor and Dtor

    inline void Add( const K& key_, T* (*CreatorFunc)(D) );
    inline shared_ptr Create(const K& key_, const D& initData_ ) const;

private:
    std::map<K, T* (*)(D) > m_creator;
};

如果用户可以像这样使用它,我会很喜欢它:

class c1
{
public:
    explicit c1(const string& st);
    ...
};

class c2
{
public:
    explicit c2();
    ...
};

c1* CreateC1(const string& st){ return new c1(st);}
c2* CreateC2(){ return new c2;}

...
//Factory<type, key, arguments>
Factory<c1, int, string> f;
f.Add(0, CreateC1);
f.Create(0, "string Arg");

//Factory<type, key>
Factory<c2, int> f2;
f2.Add(0, CreateC2);
f2.Create(0);

我确实设法通过一些丑陋的模板专业化来实现这一点。我觉得我是以错误的方式去做的。

我的解决方案:

class EmptyClass {};
template< typename T, typename K, typename D = EmptyClass>
class Factory
{
public:
    typedef std::tr1::shared_ptr<T> shared_ptr;

    inline void Add( const K& key_, T* (*CreatorFunc)(D) );
    inline shared_ptr Create(const K& key_, const D& initData_ ) const;

private:
    std::map<K, T* (*)(D) > m_creator;
};

template<>
template< typename T, typename K >
class Factory<T, K, EmptyClass >
{
public:
    typedef std::tr1::shared_ptr<T> shared_ptr;

    inline void Add( const K& key_, T* (*CreatorFunc)() );
    inline shared_ptr Create(const K& key_) const;
private:
    std::map<K, T* (*)() > m_creator;
};
如果你愿意的话,随时批评其他任何事情

1 个答案:

答案 0 :(得分:0)

如果您可以使用可变参数模板,这可能对您有用:

template< typename R, typename K, typename...Args>
class Factory
{
    using func_ptr = R*(*)(const Args & ...);
    using return_ptr = std::shared_ptr<R>;

public:
    inline void Add(const K& key_, func_ptr value);
    inline return_ptr Create(const K& key_, Args... initData_) const;

private:
    std::map<K, func_ptr> m_creator;
};

可能的实现可能如下所示:

template< typename R, typename K, typename...Args>
class Factory
{
    using func_ptr = R*(*)(const Args & ...);
    using return_ptr = std::shared_ptr<R>;

public:
    inline void Add(const K& key_, func_ptr value)
    {
        if (value != nullptr)
        {
            m_creator[key_] = value;
        }
    }

    inline return_ptr Create(const K& key_, Args... initData_) const 
    {
        auto iter = m_creator.find(key_);
        if (iter == m_creator.end())
        {
            return return_ptr(nullptr);
        }
        return return_ptr(iter->second(initData_...));
    }

private:
    std::map<K, func_ptr> m_creator;
};