【问题标题】:Is there any use for named parameters into template template parameters将命名参数转换为模板模板参数有什么用
【发布时间】:2015-05-13 13:49:19
【问题描述】:

如果我需要定义一个带有模板模板参数的模板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参数,上面的代码会产生以下错误:

错误:'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!"

并且(确定你已经注意到我之前)模板模板参数的参数中的名称被忽略了!它肯定被忽略了,因为如果不是,它应该与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忽略。

那么,问题是什么?

  1. 我的猜测正确吗?模板模板参数的命名模板参数的名称被忽略?
  2. 如果我弄错了,我误解了整个事情,那么将命名参数放入模板模板参数中是否有用?你能提供一些有用的例子吗?

至于#2 中的有用示例,我指的是只能使用模板模板参数的命名模板参数才能实现的东西。

【问题讨论】:

  • 我认为通读这个 QA:stackoverflow.com/questions/213761/… 将有助于指导为什么命名模板模板参数没有任何用处。 TTP 本质上是声明模板化参数的签名,而不是为模板化方法提供额外的模板参数。类似于声明函子时,它是(*foo)(type, type type),而不是(*foo)(type name, type name, type name)

标签: c++ templates template-templates


【解决方案1】:

[basic.scope.temp]/p1:

a 的模板参数名称的声明区域 模板 template-parameter 是最小的 template-parameter-list 在其中介绍了名称。

(现在试着说 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;

【讨论】:

  • 顺便说一句,这与函数声明非常相似。下面通过产生编译器错误来说明类比:void f(int x, decltype(x)); int main() { f(1, nullptr); }。以下编译和链接很好:void f(int x, decltype(x)); int main() { f(1, 1); } void f(int, int) {} 。这是因为x 的范围刚好足以包含它之后的decltype
  • 好吧,所以我错了:模板模板参数的命名参数没有被忽略,它根本不存在于它的模板模板类之外......我能想到的唯一用途命名模板模板参数如下:template &lt;template &lt;typename T, typename = std::allocator&lt;T&gt;&gt; class V&gt; class f {};
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 2023-01-12
  • 2011-08-28
相关资源
最近更新 更多