Edit:
Apparently, GCC allows instantiating a class template without a parameter list (when the parameters are defaulted), which is non-compliant (Clang is compliant).
I'm guessing the reason for requiring the brackets (even when the parameter list is empty) is to make it explicit that it is a template instantiation, as opposed to an actual type.
So I am steering my original question toward the differences between the class template and function template cases: why, in the second snippet, is it allowed to call a without brackets, in contrast to the instantiation of A in the first snippet? And why is it not allowed for b?
template<int i = 1>
struct A {
operator int() { return i; }
};
template<int i = 2>
using B = A<i>;
// using C = A; <-- error: missing template arguments after 'A'
using C = A<>;
int main() {
A a; // Edit: Actually should require brackets: A<> a;
// B b; <-- error: missing template arguments before 'b'
B<> b;
C c;
}
Live on Coliru
I have tried building a similar scenario with a function template instead of a class template, and there is a slight difference in the last case (C): no parameter list is required if the return type is specified in the definition of a
. I think I understand why, but I would welcome some insights. Otherwise, both cases are similar to the class template ones.
template<int i = 1>
auto a() { return i; }
// auto a() -> int { return i; }
// if the return type is specified, c can be defined as commented below
template<int i = 2>
auto b = a<i>;
// auto c = a; <-- error: unable to deduce 'auto' from 'a'
auto c = a<>;
int main() {
a();
// b(); <-- error: missing template arguments before '(' token
b<>();
c();
}
Live on Coliru
Also, are there significant differences between modern C++ standards (C++11 to C++20)? I am mostly interested in the C++17 case, but I would love to know if these things have changed, or are going to.
From what I've seen, in C++14, a class template instantiation requires a parameter list anyway, whereas a function template call does not. And I haven't found differences between C++17 and C++2a with GCC.
Template arguments [temp.arg]/4 (§12.3/4)
When template argument packs or default template-arguments are used, a template-argument list can be empty. In that case the empty
<>
brackets shall still be used as the template-argument-list.
Same wording for C++17 in §17.3/4, for C++14 & C++11 in §14.3/4.
Explicit template argument specification [temp.arg.explicit] (§12.9.1/3):
If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list
<>
itself may also be omitted.
Same wording for C++17 in §17.8.1/3, for C++14 & C++11 in §14.8.1/3.
Your
template<int i = 2> auto b = a<i>;
is a variable template for which no argument deduction will occur.
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