如果我需要定义一个带有模板模板参数的模板函数foo
,我通常会按照以下方式进行:
// Notice that the template parameter of class T is unnamed.
template <template <typename> class T> void f() { std::cout << "Yay!\n"; }
注意,模板模板参数的模板参数未命名,但我们可以为该参数指定一个名称:
// 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
参数,上面的代码会产生以下错误:
令人惊讶的是,错误:'INNER'不是一种类型
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参数中的名称被忽略了! 如果没有忽略,它应该与foo
的第二个模板参数发生名称冲突,不是吗?
参数模板-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
的类型同时被模板-模板参数和模板-模板本身使用?我认为不是这样的,据我所知,模板-模板参数中的名称会被忽略。那么,问题是什么?
- 我的猜测正确吗?模板-模板参数的命名模板参数的名称会被忽略吗?
- 如果我错了,我误解了整个事情,那么在模板-模板参数中使用命名参数有用吗?您能提供一些有用的示例吗?
(*foo)(type, type type)
,而不是(*foo)(type 名称, type 名称, type 名称)
。 - aruisdante