<>
([temp.arg.explicit]/4)。在其他情况下,通常需要模板参数列表来命名特定的模板实例化,即使它是空的。请参见simple-template-id的语法,[temp.names]/1。
作为规则的有限例外,如果类模板名称没有模板参数列表出现在需要具体类型的上下文中,那么它被称为“推导类类型的占位符”,这只允许在[dcl.type.class.deduct]中列出的特定上下文中使用。其中最常见的是变量声明,例如std::pair p("foo", 1)
,在C++17及更高版本中编译器将推导出std::pair<const char*,int>
。
在您的代码中,您尝试引用类模板Test
的特定实例化,而没有指定模板参数列表,并且不是可以推断模板参数的上下文。因此,这是不允许的。
Test
)指定为foo
的模板参数,而不是类型(比如一个类模板实例)。你需要一个接受模板模板参数的函数来处理它。#include <type_traits>
template<template<class> class T, class U> // T = Test, U = deduced to int
void foo(T<U>& bar) {
std::cout << std::is_same<T<U>, Test<int>>::value << '\n'; // true
}
int main() {
Test t;
foo<Test>(t); // now ok
}
foo<Test<>>(t);
实例化了 foo<Test<int>>(Test<int>&)
,因为 <>
让模板实例化使用模板参数的默认类型,该默认类型是 int
。