将命名参数用于模板模板参数是否有任何用途
Is there any use for named parameters into template template parameters
如果我需要用template-template参数定义一个模板foo
函数,我通常会这样做:
// Notice that the template parameter of class T is unnamed.
template <template <typename> class T> void f() { std::cout << "Yay!\n"; }
注意template-template参数的模板参数是未命名的,但是我们可以给这个参数赋一个名字:
// Now the template parameter of class T is named INNER.
template <template <typename INNER> class T> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
这似乎根本没有用,因为我无法在函数中引用 INNER
参数,上面的代码会产生以下错误:
error: 'INNER' does not name a type
令我惊讶的是 typename INNER
没有命名类型,毕竟 typename
关键字是为了命名类型。无论如何,这很容易解决:
// Now INNER is the name of the template parameter of class T and also
// the name of the second template parameter of foo.
template <template <typename INNER> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"
不过最后,INNER
参数毕竟不需要名字:
// Now the template parameter of class T is unnamed one more time,
// INNER is the name of the second template parameter of foo.
template <template <typename> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"
并且(相信你已经在我之前注意到了)template-template参数中的name被忽略了!它肯定已被忽略,因为如果不是,它应该与 foo
的第二个模板参数发生名称冲突,不是吗?
template-template参数的参数名被忽略的另一种演示:
// Now T is the name of the template parameter of class T and also
// the name of the template parameter of foo!
template <template <typename T> class T> void f()
{ std::cout << "Yay!\n"; }
// ...
f<std::valarray>(); // prints "Yay!"
名为 T
的类型被模板模板参数和模板模板本身同时使用?我不这么认为,模板模板参数中的名称被忽略了 AFAIK。
那么,问题是什么?
- 我的猜测正确吗? template-template parameters的named template parameters的名字被忽略了?
- 如果我弄错了,我误解了整个事情,那么将命名参数用于模板-模板参数中有什么用?你能提供一些有用的例子吗?
至于#2 上的有用示例,我指的是只能使用模板模板参数的命名模板参数才能实现的东西。
[basic.scope.temp]/p1:
The declarative region of the name of a template parameter of a
template template-parameter is the smallest template-parameter-list
in which the name was introduced.
(现在试着说 10 遍。)
它可以在该列表中使用。例如,
template < template<class T, T t> class TP > class foo {};
// ^ ^-----T's scope ends here
// |
// T can be used here
foo<std::integral_constant> bar;
如果我需要用template-template参数定义一个模板foo
函数,我通常会这样做:
// Notice that the template parameter of class T is unnamed.
template <template <typename> class T> void f() { std::cout << "Yay!\n"; }
注意template-template参数的模板参数是未命名的,但是我们可以给这个参数赋一个名字:
// Now the template parameter of class T is named INNER.
template <template <typename INNER> class T> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
这似乎根本没有用,因为我无法在函数中引用 INNER
参数,上面的代码会产生以下错误:
error: 'INNER' does not name a type
令我惊讶的是 typename INNER
没有命名类型,毕竟 typename
关键字是为了命名类型。无论如何,这很容易解决:
// Now INNER is the name of the template parameter of class T and also
// the name of the second template parameter of foo.
template <template <typename INNER> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"
不过最后,INNER
参数毕竟不需要名字:
// Now the template parameter of class T is unnamed one more time,
// INNER is the name of the second template parameter of foo.
template <template <typename> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"
并且(相信你已经在我之前注意到了)template-template参数中的name被忽略了!它肯定已被忽略,因为如果不是,它应该与 foo
的第二个模板参数发生名称冲突,不是吗?
template-template参数的参数名被忽略的另一种演示:
// Now T is the name of the template parameter of class T and also
// the name of the template parameter of foo!
template <template <typename T> class T> void f()
{ std::cout << "Yay!\n"; }
// ...
f<std::valarray>(); // prints "Yay!"
名为 T
的类型被模板模板参数和模板模板本身同时使用?我不这么认为,模板模板参数中的名称被忽略了 AFAIK。
那么,问题是什么?
- 我的猜测正确吗? template-template parameters的named template parameters的名字被忽略了?
- 如果我弄错了,我误解了整个事情,那么将命名参数用于模板-模板参数中有什么用?你能提供一些有用的例子吗?
至于#2 上的有用示例,我指的是只能使用模板模板参数的命名模板参数才能实现的东西。
[basic.scope.temp]/p1:
The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.
(现在试着说 10 遍。)
它可以在该列表中使用。例如,
template < template<class T, T t> class TP > class foo {};
// ^ ^-----T's scope ends here
// |
// T can be used here
foo<std::integral_constant> bar;