Конфликт имен: аргумента шаблона и у унаследованное
От: MescalitoPeyot Украина  
Дата: 12.11.10 05:54
Оценка:
struct A { struct B { static void f() { /* VC 9,10 */ } }; static void f() { /* GCC 4.x */ } };

template <class B>
struct D : public B  { static void g() { B::f(); } };

int main()
{
  D<A>::g();
  return 0;
}


Вот-с, столкнулся с такой штукой, при совпадении имени параметра шаблона (здесь это B) с именем унаследованного локального класса VC выбирает локальный класс, а GCC — параметр. Это более или менее минимальный пример, на практике у меня boost_assert(boost_type_traits(B)) обломался при портировании с gcc (надо же, пригодился всякий пожарный ассерт).
Вопрос классический и по большому счету чисто теоретический: кто виноват и что делать?
Если уже обсуждалось (что наверняка), дайте ссылку, найти не получилось, слишком много мусора по ключевым словам.
... << RSDN@Home 1.2.0 alpha 4 rev. 1138>>
Re: Конфликт имен: аргумента шаблона и у унаследованное
От: Masterkent  
Дата: 12.11.10 11:42
Оценка: 2 (1)
MescalitoPeyot:

MP>Вот-с, столкнулся с такой штукой, при совпадении имени параметра шаблона (здесь это B) с именем унаследованного локального класса VC выбирает локальный класс, а GCC — параметр.


Класс A::B — не локальный, а вложенный. В выражении B::f к B применяется обычный unqualified name lookup. При таком поиске искать имя B в зависимом базовом классе не разрешается:

14.6.2/3:
In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

MP>Вопрос классический и по большому счету чисто теоретический: кто виноват


В данном случае VC++ не соблюдает требования стандарта.

MP> и что делать?


Поменять название параметра шаблона?
Re[2]: Конфликт имен: аргумента шаблона и у унаследованное
От: MescalitoPeyot Украина  
Дата: 12.11.10 14:23
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>MescalitoPeyot:


M>14.6.2/3:

M>In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

Спасибо.

M>Поменять название параметра шаблона?


Так и сделал, поэтому и пишу — вопрос теоретический. Однако вообще довольно стремный баг.
... << RSDN@Home 1.2.0 alpha 4 rev. 1138>>
Re[2]: Конфликт имен: аргумента шаблона и у унаследованное
От: Bender Bending Rodriguez Россия  
Дата: 12.11.10 15:16
Оценка:
Здравствуйте, Masterkent, Вы писали:


M>Класс A::B — не локальный, а вложенный. В выражении B::f к B применяется обычный unqualified name lookup. При таком поиске искать имя B в зависимом базовом классе не разрешается:


А вы бы не могли пояснить, почему к Type-dependent expression B::f применяется именно unqualified name lookup?
Re[3]: Конфликт имен: аргумента шаблона и у унаследованное
От: Masterkent  
Дата: 12.11.10 16:50
Оценка: 2 (1)
Bender Bending Rodriguez:

BBR>А вы бы не могли пояснить, почему к Type-dependent expression B::f применяется именно unqualified name lookup?


Тут речь конкретно про имя B. Формального определения "unqualified name" я в стандарте не встречал. Можно людей из комитета по этому поводу потрясти. То, что в данном случае для B применяется unqualified name lookup, можно установить методом исключений. В качестве postfix-expression в некоем вызове функции имя B не используется, значит, ADL (3.4.2) тут не применяется. Qualified name lookup (3.4.3) здесь не применяется, т.к. непосредственно перед B нет ::. elaborated-type-specifier (3.4.4) здесь не образуется. Явного class member access (3.4.5), образуемого оператором . или ->, здесь тоже нет. К using-directives and namespace aliases (3.4.6) данная конструкция не относится. Остаётся только поиск по правилам ordinary unqualified name lookup (3.4.1).
Re[3]: Конфликт имен: аргумента шаблона и у унаследованное
От: sizeof_void Россия  
Дата: 12.11.10 17:08
Оценка:
Здравствуйте, Bender Bending Rodriguez, Вы писали:

BBR>Здравствуйте, Masterkent, Вы писали:



M>>Класс A::B — не локальный, а вложенный. В выражении B::f к B применяется обычный unqualified name lookup. При таком поиске искать имя B в зависимом базовом классе не разрешается:


BBR>А вы бы не могли пояснить, почему к Type-dependent expression B::f применяется именно unqualified name lookup?



Потому что тот, кто пишет код шаблона:
template<class B>
class D 
{
  void memfunc(void)
  {
    B::f();
  }
};


... по интуитивной логике ожидает вызова функции f() из того класса, которым типизирован шаблон, а не из чего-то другого под тем же именем B, даже если это базовый класс.

И если пишет, как в исходном примере:
template <class B>
struct D : public B  
{ 
 static void g() 
 { B::f(); } 
};


... то ожидает, что это вызов f() базового класса, которым типизирован шаблон, а не чето-то другого под именем B, даже если это что-то есть в этом базовом классе.

---

PS: Интересно темы соседние про шаблоны дублируют/дополняют друг друга. =)
http://rsdn.ru/forum/cpp/4034964.1.aspx
Автор: MescalitoPeyot
Дата: 12.11.10
"May the Force be with us all!" (c)
Re[4]: Конфликт имен: аргумента шаблона и у унаследованное
От: sizeof_void Россия  
Дата: 12.11.10 17:14
Оценка:
_>PS: Интересно темы соседние про шаблоны дублируют/дополняют друг друга. =)
_>http://rsdn.ru/forum/cpp/4034964.1.aspx
Автор: MescalitoPeyot
Дата: 12.11.10


Sorry, имел ввиду не эту тему, вот эту тему:
http://rsdn.ru/forum/cpp/4030635.1.aspx
Автор: pepsicoca
Дата: 09.11.10


PS: А как редактировать-то сообщения? Странный интерфейс всё-таки у этого форума... -)
"May the Force be with us all!" (c)
Re[4]: Конфликт имен: аргумента шаблона и у унаследованное
От: Masterkent  
Дата: 12.11.10 17:46
Оценка:
sizeof_void:

_>Потому что тот, кто пишет код шаблона:

_>
_>template<class B>
_>class D 
_>{
_>  void memfunc(void)
_>  {
_>    B::f();
_>  }
_>};
_>


_>... по интуитивной логике ожидает вызова функции f() из того класса, которым типизирован шаблон, а не из чего-то другого под тем же именем B, даже если это базовый класс.


Когда базовый класс non-dependent, он вполне может скрыть параметр шаблона:

struct B
{
    static void f() {}
};

template <class B>
    struct D : ::B
{
    static void g()
    {
        B::f(); // B - это injected-class-name базового класса ::B
    }
};

int main()
{
    D<int>::g();
}

Тут уже GNU C++ 4.5.0 нарушает стандарт, трактуя B как параметр шаблона.

14.6.1/7:

In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each base class which does not depend on a template-parameter (14.6.2), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (3.3.7).

Re[5]: Конфликт имен: аргумента шаблона и у унаследованное
От: Masterkent  
Дата: 12.11.10 17:49
Оценка:
sizeof_void:

_>PS: А как редактировать-то сообщения? Странный интерфейс всё-таки у этого форума... -)


Давно уже просим ввести такую опцию: http://rsdn.ru/forum/rsdn/3760641.flat.aspx
Автор: nen777w
Дата: 03.04.10
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.