Как я могу использовать любую функцию в качестве явного параметра шаблона, БЕЗ превращения его в аргумент функции? - PullRequest
0 голосов
/ 27 февраля 2019

Есть несколько похожих вопросов, но все они, кажется, танцуют вокруг этой проблемы.

У меня есть функция, в которой мне нужно выполнить некоторую обработку аргументов перед тем, как передать аргументы конструктору ИЛИфабричная функция (по крайней мере, обычные функции и статические функции-члены, потенциально функторы и обычные функции-члены).

Я выяснил, как передавать аргументы конструктору типа, но не могу понятькак это сделать для заводских функций без передачи функции в качестве параметра.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...