工厂功能

假设我们要编写一个接受任意参数列表的工厂函数,并将那些未修改的参数传递给另一个函数。这种函数的一个例子是 make_unique,它用于安全地构造 T 的新实例并返回拥有该实例的 unique_ptr<T>

关于可变参数模板和右值引用的语言规则允许我们编写这样的函数。

template<class T, class... A>
unique_ptr<T> make_unique(A&&... args)
{
    return unique_ptr<T>(new T(std::forward<A>(args)...));
}

椭圆 ... 的使用表示参数包,其表示任意数量的类型。编译器会将此参数包扩展为调用站点上正确数量的参数。然后使用 std::forward 将这些参数传递给 T 的构造函数。需要此函数来保留参数的 ref 限定符。

struct foo
{
    foo() {}
    foo(const foo&) {}                    // copy constructor
    foo(foo&&) {}                         // copy constructor
    foo(int, int, int) {}
};

foo f;
auto p1 = make_unique<foo>(f);            // calls foo::foo(const foo&)
auto p2 = make_unique<foo>(std::move(f)); // calls foo::foo(foo&&)
auto p3 = make_unique<foo>(1, 2, 3);