I have a the following template and specialization (this code is not correct, but hopefully demonstrates my intent well enough):
template <typename T> widget &&make_widget(T &&val) { // (1)
return std::move(widget(std::forward<T>(val)));
}
template <> widget &&make_widget(void) { // (2)
return std::move(widget());
}
The intent is to have a factory function that can be called like this:
make_widget(arbitrary_function());
And have it choose the default constructor if arbitrary_function returns void.
However, with clang 3.7 I get the following error:
error: no function template matches function template specialization 'make_widget'
pointing to the line of (2). How can I implement this correctly?
You can't do this. It's impossible to create a function that has a parameter of type void. What you can do is make the function variadic, like make_unique.
template <typename... T>
widget make_widget(T&&... val) {
return widget(std::forward<T>(val)...);
}
Then if you want to do something like
auto w = make_widget(void_function());
there is nothing stopping you from just doing instead:
void_function();
auto w = make_widget();
or even, if you really need it to be one statement for some reason,
auto w = (void_function(), make_widget());
Three further notes:
std::move in the return statement since the result of calling the constructor is already an rvalue.make_widget function if forwarding its arguments to the widget constructor is the only thing it does. Note that make_unique takes care of calling new for you, and that make_tuple deduces the template arguments for the tuple itself. Your make_widget function doesn't do anything like that.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With