Ошибка копиляции шаблона в clang
От: dolgop8791  
Дата: 14.07.15 12:27
Оценка:
Добрый день.

Есть код:

namespace CORBA {
    class Any {};
}
class AnyTest {};

namespace PortableGroup {                    
    class Holder {};
}
class HolderTest {};

template<typename Any, typename Ptr>
class TEST { 
public:   
    TEST () {
           Any any;
           any <<= this->x_;
    }
private:
    Ptr x_;
};                                                                                                 

void operator<<= (CORBA::Any&, PortableGroup::Holder*);
void operator<<= (CORBA::Any&, HolderTest*);
void operator<<= (AnyTest&, PortableGroup::Holder*); // если перенести описание оператора перед TEST, пример скомпилируется.

void test (PortableGroup::Holder * excep_holder) {
    TEST<AnyTest, PortableGroup::Holder*>  test1; 
    TEST<CORBA::Any, HolderTest*>  test2;
    TEST<CORBA::Any, PortableGroup::Holder*>  test3;  
}


Он компилится msvc, gcc и icc. А вот clang не нравится test3:

16 : error: no viable overloaded '<<='
any <<= this->x_;
~~~ ^ ~~~~~~~~
29 : note: in instantiation of member function 'TEST::TEST' requested here

Если перенести описание соответствующего оператора выше определения TEST, то пример скомпилируется. Вопрос в том кто же прав из компиляторов и почему clang-у не нравится только третий вариант.
Re: Ошибка копиляции шаблона в clang
От: watchmaker  
Дата: 14.07.15 12:56
Оценка: 2 (1) +1
Здравствуйте, dolgop8791, Вы писали:


D>Вопрос в том кто же прав из компиляторов и почему clang-у не нравится только третий вариант.

Unqualified lookup in templates


D>Если перенести описание соответствующего оператора выше определения TEST, то пример скомпилируется.

Либо так, либо заворачивать описания в соответствующие namespace'ы чтобы они через ADL находились.
Re: Ошибка копиляции шаблона в clang
От: Evgeny.Panasyuk Россия  
Дата: 14.07.15 13:07
Оценка:
Здравствуйте, dolgop8791, Вы писали:

D>Если перенести описание соответствующего оператора выше определения TEST, то пример скомпилируется. Вопрос в том кто же прав из компиляторов


Думаю прав Clang. Вот здесь
Автор: Evgeny.Panasyuk
Дата: 08.11.13
было обсуждение на схожую тему.
Конкретная цитата из стандарта:

14.6.4 Dependent name resolution [temp.dep.res]
In resolving dependent names, names from the following sources are considered:
— Declarations that are visible at the point of definition of the template.
— Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context.

То есть поиск происходит в контексте определения шаблона (в твоём случае это конструктор TEST), и в namespace'ах ассоциированных с типами параметров функции — причём в этом случае используется контекст instantiation (в твоём случае это функция test (хотя тут немного сложнее ("the end of the translation unit is also considered a point of instantiation") — смотри дискуссию по ссылке, но это не важно для этого примера))

D>и почему clang-у не нравится только третий вариант.


Ему не нравится вариант void operator<<= (CORBA::Any&, PortableGroup::Holder*);

Здесь ни в одном из namespace ассоциированных с типами параметров нет нужного оператора, и поиск происходит только в "at the point of definition of the template".
В двух других случаях оператор есть в namespace ассоциированным с AnyTest, либо с HolderTest — это глобальный namespace — и поиск происходит в том числе в этом namespace в instantiation context.
Отредактировано 14.07.2015 13:08 Evgeny.Panasyuk . Предыдущая версия .
Re[2]: Ошибка копиляции шаблона в clang
От: dolgop8791  
Дата: 14.07.15 13:13
Оценка:
D>>Вопрос в том кто же прав из компиляторов и почему clang-у не нравится только третий вариант.
W>Unqualified lookup in templates

Спасибо, вопрос закрыт.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.