Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

alias template substitution and deduction failure with gcc

I believe that I have found a problem with gcc's alias template handling. Essentially, gcc appears to fail to correctly substitute the alias's template-id for an alias template instantiation when referring to the types by reference.

I was able to whittle a messy real-world problem down to a minor variation on the non-normative example provided in the C++ 11 standard section 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
}

As noted above, clang 3.3 (recent pull from svn) and gcc (4.7.2, 4.8.0, and 4.8.1) agree on the handling of f1/g1 in conformance with the standard, but differ on the handling of f2/g2 (to be clear, all tested versions of gcc accept the call to f2() and error on the call to g2()). The difference between f1/g1 and f2/g2 is of course that the latter pair uses a reference parameter.

All indications, both in this example and in my real problem, are that gcc is not correctly converting the type of the instantiation of the alias template (e.g. Vec<int>) to the aliased type (e.g. vector<int, allocator<int>>) prior to trying to deduce the template parameter for the instantiations of f2 and g2.

My question is: first, is indeed gcc incorrect and clang correct here, and second, is there any straightforward way (other than not using the alias template) to convince gcc to reject f2 and match g2.

like image 689
Stephen C. Pope Avatar asked May 31 '13 16:05

Stephen C. Pope


1 Answers

Indeed this is a GCC bug. One workaround is to simply add a typedef.

   typedef Vec<int> vit;
   vit v;

Given that this is effective, an identity metafunction would probably also work.

like image 168
Potatoswatter Avatar answered Nov 08 '22 19:11

Potatoswatter