The following code compiles with VS15 Community and prints out "Hello".
#include <functional>
#include <iostream>
template<typename T>
using void_template_alias_t = void;
template<typename T>
using Func = std::function<void( T )>;
template<typename T>
using FuncVoid = Func<void_template_alias_t<T>>;
int main()
{
FuncVoid<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
I think this is not allowed to compile.
I was playing around, the code was a bit more complex. I naively expected this to work, but suddenly realized that this code should not compile because you can't make a Func<void>
(or am I wrong with this?).
Edit: The following more simplified version does not compile.
#include <functional>
#include <iostream>
template<typename T>
using Func = std::function<void( T )>;
int main()
{
Func<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
Or is it simply a compiler bug?
That. As mentioned by @T.C., CWG #577 is relevant:
[…] there was some concern expressed over the treatment of function templates and member functions of class templates if the C++ rule were changed: for a template parameter
T
, would a function taking a single parameter of typeT
become a no-parameter function if it were instantiated withT = void
?
This is a justified complaint, but unfortunate for you, member functions/member function templates and type-ids were affected equally by the resolution:
A parameter list consisting of a single unnamed parameter of non-dependent type
void
is equivalent to the an empty parameter list.
thus both your snippets are ill-formed, as the parameter's type is indeed dependent.
Is it a correct implementation, if not, how would it look like?
There is no correct implementation. If you need a function type with an empty parameter list, you'll have to specify that independent from template parameters.
So why is the code above compiling and working as I first expected?
My best guess: VC++ does the substitution of void_template_alias_t<T>
after assuring that the parameter type is not a dependent type "cv void
", but before making the "void
-> empty list transformation". However, it's often hard to comprehend how VC++ (or any compiler, for that matter) thinks internally.
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