Есть несколько похожих вопросов, но все они, кажется, танцуют вокруг этой проблемы.
У меня есть функция, в которой мне нужно выполнить некоторую обработку аргументов перед тем, как передать аргументы конструктору ИЛИфабричная функция (по крайней мере, обычные функции и статические функции-члены, потенциально функторы и обычные функции-члены).
Я выяснил, как передавать аргументы конструктору типа, но не могу понятькак это сделать для заводских функций без передачи функции в качестве параметра.
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.