如何将任何函数用作显式模板参数,而又不使其成为函数的参数?

时间:2019-02-26 23:57:20

标签: templates function-pointers template-meta-programming functor

有几个类似的问题,但似乎都围绕着这个问题跳舞。

我有一个函数,需要在对参数进行传递之前将参数传递给构造函数或工厂函数(至少是常规函数和静态成员函数,以及可能的函子和常规成员函数)。

我已经弄清楚了如何将参数传递给类型的构造函数,但是我不知道如何在不将函数作为参数传递的情况下对工厂函数执行此操作。

template <typename T,
          typename std::enable_if<std::is_class<T>::value, int>::type = 0,
          typename... Args>
SmartPtr<T> makePtr(Args&&... args)
{
    // Process args...
    T* temp = new T(std::forward<Args>(args)...);
    return SmartPtr<T>(temp);
}

// This is what I'm not sure how to do
template <typename F, typename... Args, /* An arbitrary function signature or something*/>
SmartPtr</*return type of F*/> makePtr(Args&&... args)
{
    // Process args...
    /*return type of F*/ temp = F(std::forward<Args>(args)...);
    return SmartPtr</*return type of F*/>(temp);
}

我希望能够像这样使用这些功能:

class MyClass {
    public:
        MyClass(int value) : m_value(value) {}
        static MyClass* factory(int value)
        {
            return new MyClass(value);
        }
        MyClass* clone(MyClass* other)
        {
            return MyClass::factory(other.m_value);
        }
    private:
        int m_value;
};

MyClass* otherFactory(int value)
{
    return new MyClass(value);
}

int main(int argc, char* argv[])
{
    MyClass temp(-1);
    MyClass* temp2 = new MyClass(0);
    auto ptr = makePtr<MyClass>(1);
    auto ptr2 = makePtr<MyClass::factory>(2);
    auto ptr3 = makePtr<otherFactory>(3);
    auto ptr4 = makePtr<temp.clone>(4); // What would the proper syntax be for this one?
    auto ptr5 = makePtr<temp2->clone>(5); // What would the proper syntax be for this one?
}

我希望将其与构造函数或工厂方法具有任何数量参数的任何类和工厂方法一起使用。我知道如果实际上将函数作为参数传递,我可以做类似的事情,但是我希望避免这种情况,而希望使用一致的接口。

// This is what I would like to avoid
template <typename F,
          typename std::enable_if<!std::is_class<T>::value, int>::type = 0,
          typename... Args>
SmartPtr<typename std::remove_pointer<typename std::result_of<F(Args...)>::type>::type>
makePtr(F f, Args&&... args) {
    using R = typename std::remove_pointer<typename std::result_of<F(Args...)>::type>::type;
    // Process arguments...
    R* temp = f(args...);
    return SmartPtr<R>(temp);
}

int main(int argc, char* argv[])
{
    MyClass temp(-1);
    MyClass* temp2 = new MyClass(0);
    auto ptr = makePtr<MyClass>(1);
    auto ptr2 = makePtr(MyClass::factory, 2);
    auto ptr3 = makePtr(otherFactory, 3);
    auto ptr4 = makePtr(temp.clone, 4); // What would the proper syntax be here?
    auto ptr5 = makePtr(temp2->clone, 5); // What would the proper syntax be here?
}

我正在使用c ++ 11。

0 个答案:

没有答案
相关问题