Нет, без дополнительной функции make сделать это невозможно.
Причина, по которой он не работает с конструкторами, заключается в том, что это было бы нелепо сложно. Учтите это:
template <typename T>
struct Foo
{
Foo(const T& val) { ... }
Foo(const Foo<T>& other) { ... } // Copy constructor
};
Foo<int> x;
Что если я тогда позвоню:
Foo(x);
Это дает мне Foo< Foo<int> >
или я вызываю конструктор копирования для Foo<int>
?
Это было бы неоднозначно в слишком многих местах, поэтому необходима дополнительная функция.
Обратите внимание, что вы можете немного автоматизировать создание функций make, используя шаблоны шаблонов:
template <template <typename> class TemplateClass, typename Type>
TemplateClass<Type> make(const Type& x)
{
return TemplateClass<Type>(x);
}
Тогда вы можете использовать:
make<SomeClass>(123); // returns a SomeClass<int>