Подтвердить что ты не робот

Alias замену шаблона и дедукцию с gcc

Я считаю, что я нашел проблему с обработкой шаблона gcc alias. По сути, gcc, похоже, не может правильно подставить идентификатор шаблона псевдонима для создания шаблона псевдонима, ссылаясь на типы по ссылке.

Я смог уничтожить беспорядочную проблему реального мира до незначительной вариации на ненормативном примере, представленном в стандартном разделе С++ 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
}

Как отмечалось выше, 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.

4b9b3361

Ответ 1

Действительно, это ошибка GCC. Одним из способов является просто добавить typedef.

   typedef Vec<int> vit;
   vit v;

Учитывая, что это эффективно, вероятно, также будет работать метафорум идентичности.

Ответ 2

Похоже, что компилятор имеет проблему с выводом. Явное обращение к шаблону позволяет работать - я не могу говорить, почему 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

Для gcc (GCC) 4.7.2 20121109 (Red Hat 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