2013-05-31 1 views
13

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

я смог укоротить грязные реальные проблемы вплоть до незначительного изменения на ненормативном примере, приведенном в 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 
} 

Как отмечалось выше, 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, конечно, заключается в том, что последняя пара использует контрольный параметр.

Все признаки, как в этом примере и в моей реальной проблемой, является то, что НКУ не правильно преобразовывать тип конкретизации шаблона псевдонима (например, Vec<int>) к совмещенного типа (например, vector<int, allocator<int>>) до пытается вывести параметр шаблона для экземпляров f2 и g2.

Мой вопрос: во-первых, это действительно gcc некорректно и корректно сказано здесь, а во-вторых, есть ли простой способ (кроме использования шаблона псевдонима), чтобы убедить gcc отклонить f2 и сопоставить g2.

+0

@DyP Спасибо за ссылку, но, к сожалению, это немного по-другому - там нет удержания. В моем вопросе проблема - это время точки замены шаблона псевдонима относительно точки дедукции, так сказать. f1 требуется отклонить стандартом, потому что тип v действительно 'vector >' и не может соответствовать параметру шаблона одного параметра шаблона. –

+1

О, страшно, я, должно быть, пропустил это. [Temp.alias]/2 "Примечание. Имя шаблона псевдонима никогда не выводится." – dyp

+0

Ваш 'Vec ' и 'vector >' упоминания в среднем абзаце должны быть обратными. (Разбор HTML избавляется от материала между угловыми скобками, поскольку это не кодовое цитирование.) Я попытался включить их для вас, но похоже, что мое редактирование было отклонено. –

ответ

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 

Для 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 
1

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

typedef Vec<int> vit; 
    vit v; 

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