Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specialize a template for void parameter

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?

like image 739
Tamás Szelei Avatar asked Dec 27 '25 19:12

Tamás Szelei


1 Answers

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:

  • You should nix the std::move in the return statement since the result of calling the constructor is already an rvalue.
  • Never return a reference (even rvalue reference) to a temporary! It will always become a dangling reference.
  • There is no point to the 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.
like image 67
Brian Bi Avatar answered Dec 30 '25 23:12

Brian Bi