使用gcc替换模板替换和演绎失败

Ste*_*ope 13 c++ gcc templates language-lawyer c++11

我相信我发现了gcc的别名模板处理问题.实质上,当通过引用引用类型时,gcc似乎无法正确地将别名的template-id替换为别名模板实例化.

我能够将一个混乱的现实问题简化为C++ 11标准部分temp.alias(14.5.7/2)中提供的非规范示例的微小变化:

#include <vector>

using namespace std;

template <class T>
using Vec = vector<T, allocator<T>>;

template <template <class> class TT>
void f1(TT<int> v);

template <template <class> class TT>
void f2(TT<int>& v);

template <template <class, class> class TT>
void g1(TT<int, allocator<int>> v);

template <template <class, class> class TT>
void g2(TT<int, allocator<int>>& v);

void foo()
{
   Vec<int> v;

   f1(v);    // gcc and clang both correctly yield no matching function error
   g1(v);

   f2(v);    // clang yields a no matching function error
   g2(v);    // gcc yields a no matching function error
}
Run Code Online (Sandbox Code Playgroud)

如上所述,clang 3.3(最近来自svn)和gcc(4.7.2,4.8.0和4.8.1)同意f1/g1的处理符合标准,但f2处理不同/ g2(很明显,gcc的所有测试版本都接受对f2()的调用,并且在调用g2()时出错.f1/g1和f2/g2之间的差异当然是后一对使用参考参数.

在此示例和我的实际问题中的所有指示都是在尝试推导实例化的模板参数之前,gcc未正确地将别名模板(例如Vec<int>)的实例化的类型转换为别名类型(例如vector<int, allocator<int>>). f2和g2.

我的问题是:首先,确实gcc不正确并且clang在这里正确,其次,是否有任何直接的方式(除了不使用别名模板)来说服gcc拒绝f2并匹配g2.

haz*_*dev 0

看起来编译器的推断有问题。显式调用模板可以解决问题——我无法解释为什么 gcc 无法像 icpc 或 clang 那样进行推断。

对于icpc(ICC)13.1.0 20130121:

f1<Vec> (v);    // gcc and clang both correctly yield no matching function error
g1(v);
f2<Vec>(v);    // clang yields a no matching function error
g2(v);    // gcc yields a no matching function error
Run Code Online (Sandbox Code Playgroud)

对于海湾合作委员会(GCC)4.7.2 20121109(红帽4.7.2-8):

f1<Vec> (v);    // gcc and clang both correctly yield no matching function error
g1(v);
f2<Vec>(v);    // clang yields a no matching function error
g2<vector>(v);    // gcc yields a no matching function error
Run Code Online (Sandbox Code Playgroud)