Consider this snippet of code, which uses the common idiom of having a function template construct an instance of a class template specialized on a deduced type, as seen with
make_foo
is in the same ballpark as "right", but foo
isn't. The foo
constructor currently only accepts a non-deduced T &&
, and forwarding there is probably not what you mean (but see @nosid's comment). All in all, foo
should take a type parameter, have a templated constructor, and the maker function should do the decaying:
template
struct foo
{
T v_;
template
foo(U && u) : v_(std::forward(u)) { }
};
template
foo::type> make_foo(U && u)
{
return foo::type>(std::forward(u));
}
In C++14 the maker function becomes a bit simpler to write:
template
auto make_foo(U && u)
{ return foo>(std::forward(u)); }
As your code is written now, int a; make_foo(a);
would create an object of type foo
. This would internally store an int
, but its constructor would only accept an int &
argument. By contrast, make_foo(std::move(a))
would create a foo
.
So the way you wrote it, the class template argument determines the signature of the constructor. (The std::forward
still makes sense in a perverted kind of way (thanks to @nodis for pointing this out), but this is definitely not "forwarding".)
That is very unusual. Typically, the class template should determine the relevant wrapped type, and the constructor should accept anything that can be used to create the wrapped type, i.e. the constructor should be a function template.