gcc 和 clang 是否没有正确推断模板别名类型?

Are gcc and clang not properly inferring template alias types?

我有以下简单示例:

// Function we are interested in using.
template<template<typename> class A>
void B(A<int>&) { }

template<typename C, typename D>
class E { };

// "Adapter" to have only one template argument for E.
template<typename F>
using G = E<F, int>;

int main()
{
  G<int> h;
  B(h); // fails!
  // B<G>(h); // does not fail!
}

在这个例子中,我们使用了模板别名,以便拥有正确数量的模板参数来调用函数 C()。当然,这是从导致此问题的实际情况中提取的,因此解决方法不是这里的解决方案(也不是我正在寻找的)。

gcc 给出:

test2.cpp: In function ‘int main()’:
test2.cpp:14:6: error: no matching function for call to ‘B(G<int>&)’
   B(h);
      ^
test2.cpp:2:6: note: candidate: template<template<class> class A> void B(A<int>&)
 void B(A<int>&) { }
      ^
test2.cpp:2:6: note:   template argument deduction/substitution failed:
test2.cpp:14:6: error: wrong number of template arguments (2, should be 1)
   B(h);
      ^
test2.cpp:1:35: note: provided for ‘template<class> class A’
 template<template<typename> class A>

根据标准,这是 gcc 的正确输出吗?在我看来,这种语言似乎应该允许在这种情况下对模板别名进行适当的类型推断。

gcc 是正确的。代码格式错误。模板别名是透明的 - 因此 h 只是类型 E<F, int>,而 E 不匹配 template <typename> class,因为它需要多个模板参数。

B<G>(h); 有效,因为 G 确实匹配模板模板参数并且不会发生推导。