是否可以创建一个可用于创建任何类的"新"实例的泛型方法或类?

Kai*_*zay 6 c++ templates variadic-templates perfect-forwarding c++11

通常情况下,如果我有a Foo或a Bar,我会做类似的事情:

Foo* foo = new Foo();

Bar* bar = new Bar(2,3,5);
Run Code Online (Sandbox Code Playgroud)

有没有办法使用模板或宏,我可以构建一个函数,这样我可以做类似的事情:

Foo* foo = MyAwesomeFunc(Foo);
Bar* bar = MyAwesomeFunc(Bar,2,3,5); 
Run Code Online (Sandbox Code Playgroud)

实际的方法签名MyAwesomeFunc对我来说并不重要.

Foo并且Bar不需要以任何可能的方式相关,并且可能具有完全不同的构造函数.此外,我可能希望将来支持任意数量的类,而无需实际修改代码MyAwesomeFunc

这可能吗 ?一个简单的办法是同时具有FooBar一些类型继承,也就是说Baz,并已重载方法返回一个Baz,你转换回FooBar...

Baz* MyAwesomeFunc(){
    return new Foo();
}

Baz* MyAwesomeFunc(int a,int b,int c){
    return new Bar(a,b,c);
}
Run Code Online (Sandbox Code Playgroud)

但这里的问题是你必须写:

  1. 支持每个类的方法
  2. 并为每种构造函数签名.

目标是编写单个类,方法或宏,我们可以调用一个函数(并传递任何参数),但调用传入的对象的正确构造函数.这可能吗 ?

这个问题的目的是简单地探究是否可以在C++中做这样的事情.请不要提出共享指针,独特的指针,使用新的陷阱,因为这是偏离主题.

编辑:我想只使用STL,并避免使用像Boost ....

son*_*yao 8

从C++ 11开始,你可以使用可变参数模板完美的前向.例如,编写一个模板函数,它完美地将其参数转发给具有template参数指定类型的对象的构造函数.

template <typename T, typename... Ts>
T* MyAwesomeFunc(Ts&&... params){
    return new T(std::forward<Ts>(params)...);
}
Run Code Online (Sandbox Code Playgroud)

然后用它作为

Foo* foo = MyAwesomeFunc<Foo>();
Bar* bar = MyAwesomeFunc<Bar>(2,3,5); 
Run Code Online (Sandbox Code Playgroud)

  • @John,编译错误.从外面看它看起来并不完美,但有办法解决这个问题(概念和仿真). (5认同)
  • @John如果提供的参数与对象的构造函数不匹配,那么您将得到编译器错误; 它与你写"新吧(某事)"时的情况相同;`. (2认同)

Gam*_*bit 8

是的,您可以使用模板和C++ 11的"完美转发":

#include <type_traits>
#include <utility>

template<typename T, typename... Args>
T* createNew(Args&&... args)
{
  static_assert(std::is_constructible<T, Args...>::value, "T is not constructible with these arguments");
  return new T(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以查看C++ 11 std::make_unique和"智能指针" 什么是智能指针,何时应该使用?

  • 因为您可以设置自己的消息,并且它不会在可怕的编译器错误中丢失. (4认同)