编辑:
显然,GCC允许实例化没有参数列表(默认情况下为参数列表)的类模板,该列表不符合标准(符合Clang)。
我猜测要求使用方括号(即使参数列表为空)的原因是要明确表明它是模板实例化,而不是实际类型。
因此,我将最初的问题引向类模板和函数模板用例之间的区别:为什么在第二个代码段中,与第一个代码段中的A实例化相比,它允许调用不带括号的a?为什么不允许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;
}
我尝试使用函数模板而不是类模板构建类似的场景,并且在最后一种情况(C)中存在细微差别:如果在{的定义中指定了返回类型,则不需要参数列表{1}}。我想我理解原因,但是我欢迎您提供一些见解。否则,这两种情况都类似于类模板的情况。
a
而且,现代C ++标准(C ++ 11到C ++ 20)之间有显着差异吗?我对C ++ 17案例最感兴趣,但是我很想知道这些事情是否已经改变或将会改变。
据我所知,在C ++ 14中,类模板实例化始终需要一个参数列表,而函数模板调用则不需要。而且我还没有发现带有GCC的C ++ 17和C ++ 2a之间的区别。
答案 0 :(得分:5)
Template arguments [temp.arg]/4 (§12.3/4)
使用模板参数包或默认模板参数时,模板参数列表可以为空。 在这种情况下,空的
<>
括号仍应用作模板参数列表 。
第1.7.3 / 4节中的C ++ 17措辞与第14.3 / 4节中的C ++ 14和C ++ 11措辞相同。
Explicit template argument specification [temp.arg.explicit] (§12.9.1/3):
如果可以推导出所有模板参数,则可以全部省略;在这种情况下,空模板参数列表
<>
本身也可以省略。
第17.8.1 / 3节中的C ++ 17措辞与第14.8.1 / 3节中的C ++ 14和C ++ 11措辞相同。
您的
template<int i = 2> auto b = a<i>;
是一个变量模板,对于该模板不会进行任何参数推导。