I have a variadic class template.
template<typename... Ts>
class Foo {
public:
Foo(Ts... values) {
}
};
Using this class, I can create objects with/without parameters.
Foo<int> f1{1};
Foo<int, double> f2{1, 2.0};
Foo f3{};
I can even create a shared pointer.
auto f4 = std::make_shared<Foo<int, double>>(1, 2.0);
The problem arises the moment I want to create a shared pointer without parameters. Neither of these approaches work:
auto f5 = std::make_shared<Foo>();
Foo f5{}
auto f5_sharedPtr = std::make_shared(std::move(f5));
main.cpp:27:37: error: no matching function for call to ‘make_shared class Foo>()’
auto f5 = std::make_shared<Foo>();
^
In file included from /usr/include/c++/7/memory:81:0,
from main.cpp:9:
/usr/include/c++/7/bits/shared_ptr.h:703:5: note: candidate: template std::shared_ptr<_Tp> std::make_shared(_Args&& ...)
make_shared(_Args&&... __args)
^~~~~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:703:5: note: template argument deduction/substitution failed:
The correct syntax is std::make_shared<Foo<>>()
Foo<int,double>
is a type, which is why std::make_shared<Foo<int,double>>
works.
The problem is that Foo
, without the <>
is a template, and is not a type, and results in a compilation error.
Edit:
The code
Foo f3{};
is sort of a special case. In this case, your are using the C++17 feature Class Template Argument Deduction. This deduces the type of f3
as Foo<>
This is also what lets you write
Foo f4{1, 2.0}
Which would deduce the type of f4 as a Foo<int, double>
.
The cppreference page gives more examples of when this feature can be used