Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using 'void' template arguments in C++

Take the following minimal example:

using Type1 = std::function<void(void)>;  template <typename T> using Type2 = std::function<void(T)>;  Type1 whyDoesThisWork; Type2<void> andYetThisDoesNot; 

If the second type alias, I get the error "Argument may not have 'void' type". (I tested with Xcode 4.5, Clang/c++11/libc++, OS X 10.7.)

I find this curious: I would have expected Type1 and Type2<void> to behave identically. What's going on here? And is there a way to rewrite the second type alias so I can write Type2<void> and get std::function<void(void)> instead of an error?

Edit I should probably add that the reason I want this is to allow for something like the following:

template <typename ... T> using Continuation = std::function<void(T...)>;  auto someFunc = []() -> void {   printf("I'm returning void!\n"); };  Continuation<decltype(someFunc())> c; 

Continuation<decltype(someFunc())> becomes Continuation<void> and I get the error.

like image 757
Nick Hutchinson Avatar asked Nov 14 '12 02:11

Nick Hutchinson


People also ask

Why do we use :: template template parameter?

Correct Option: D. It is used to adapt a policy into binary ones.

What is template argument deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

What are template arguments?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.


1 Answers

I don't have an actual answer, only what I said in the comment: You can't have void as a function type, as in:

int foo(int, char, void, bool, void, void);     // nonsense! 

I believe that T(void) is only allowed as a compatibility notation for C (which distinguishes declarations and prototypes, very differently from C++, and which needs to be able to say "no arguments").

So, the solution should be variadic:

template <typename ...Args> using myType = std::function<void(Args...)>; 

That way you can properly have no arguments:

myType<> f = []() { std::cout << "Boo\n"; } 
like image 62
Kerrek SB Avatar answered Oct 09 '22 13:10

Kerrek SB