Зависимые имена в шаблонах
От: seejay Россия  
Дата: 19.10.13 12:10
Оценка: 2 (1)
Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?

#include <iostream>
using namespace std;

template<class T> struct C;

struct A{};

template<class T>
struct C{
    void func(C<T>*){cout<<"C<T>::func"<<endl;}
};

template<class T>
struct M: public C<T>
{
    C<T>* pt;
    void f(){ func(pt); } // Ошибка. Имя func не найдется
};

int main() {
    M<A> m;
    m.f();

    return 0;
}
Re: Зависимые имена в шаблонах
От: Abyx Россия  
Дата: 19.10.13 13:21
Оценка: 1 (1) -1
Здравствуйте, seejay, Вы писали:

S>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?


потому что надо писать this->func.
соберите код g++, он Вам об этом скажет — http://coliru.stacked-crooked.com/a/ff10fdbcb39e285c
то, что VC++ иногда позволяет писать без this->, это расширение VC++.
In Zen We Trust
Re[2]: Зависимые имена в шаблонах
От: seejay Россия  
Дата: 19.10.13 13:34
Оценка:
Здравствуйте, Abyx, Вы писали:

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


S>>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?


A>потому что надо писать this->func.

A>соберите код g++, он Вам об этом скажет — http://coliru.stacked-crooked.com/a/ff10fdbcb39e285c
A>то, что VC++ иногда позволяет писать без this->, это расширение VC++.

Я не об этом спрашиваю. Как сделать имя видимым я знаю. Можно еще добавить using или полностью квалифицировать имя.
Вопрос в другом. Почему без дополнительных квалификаторов это имя не может быть найдено?
Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое. ADL должен найти, вроде бы, по параметру, но не находит.
Re[3]: Зависимые имена в шаблонах
От: Abyx Россия  
Дата: 19.10.13 14:10
Оценка:
Здравствуйте, seejay, Вы писали:

S>Вопрос в другом. Почему без дополнительных квалификаторов это имя не может быть найдено?

S>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое. ADL должен найти, вроде бы, по параметру, но не находит.
проблема в том, что С это зависимый тип, и у него может быть специализация без func().
по этому компилятор не ищет имена в зависимых базовых типах.
In Zen We Trust
Re[3]: Зависимые имена в шаблонах
От: Abyx Россия  
Дата: 19.10.13 14:29
Оценка: 2 (1) +1
Здравствуйте, seejay, Вы писали:

S>ADL должен найти, вроде бы, по параметру, но не находит.


так ADL вроде не ищет функции-члены. только свободные функции (в т.ч. friend функции)
In Zen We Trust
Re[3]: Зависимые имена в шаблонах
От: uzhas Ниоткуда  
Дата: 19.10.13 18:29
Оценка: -1
Здравствуйте, seejay, Вы писали:

S>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое.


func is not dependent name, потому что это имя unqualified
ссылка по теме: http://stackoverflow.com/questions/1527849/how-do-you-understand-dependent-names-in-c/1527910#1527910
Re[4]: Зависимые имена в шаблонах
От: seejay Россия  
Дата: 20.10.13 09:29
Оценка: +1
Здравствуйте, uzhas, Вы писали:

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


S>>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое.


U>func is not dependent name, потому что это имя unqualified

U>ссылка по теме: http://stackoverflow.com/questions/1527849/how-do-you-understand-dependent-names-in-c/1527910#1527910

Тут вы не правы, функция с параметрами зависящими от параметра шаблона — это зависимое имя.
Например, если закоментировать вызов m.f() ошибки не будет

#include <iostream>
using namespace std;

struct A{};

template<class T>
struct C
{
    void func(C<T>*){cout<<"C<T>::func"<<endl;}
};

template<class T>
struct M: public C<T>
{
    C<T>* pt;
    void f(){ func(pt); }   // тут нет ошибки (вызов в main закоментирован) т.к. func зависимое имя
    void m(){ asd();}    // тут ошибка. т.к. asd независимое имя, должно быть видимо без инстанцирования
};

int main() {
    M<A> m;
    //m.f();    // f() не инстанцируем, ошибки нет
    return 0;
}
Re[4]: Зависимые имена в шаблонах
От: seejay Россия  
Дата: 20.10.13 09:30
Оценка:
Здравствуйте, Abyx, Вы писали:

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


S>>Вопрос в другом. Почему без дополнительных квалификаторов это имя не может быть найдено?

S>>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое. ADL должен найти, вроде бы, по параметру, но не находит.
A>проблема в том, что С это зависимый тип, и у него может быть специализация без func().
A>по этому компилятор не ищет имена в зависимых базовых типах.

А разве это касается зависимых имён?
Re[4]: Зависимые имена в шаблонах
От: seejay Россия  
Дата: 20.10.13 09:33
Оценка:
Здравствуйте, Abyx, Вы писали:

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


S>>ADL должен найти, вроде бы, по параметру, но не находит.


A>так ADL вроде не ищет функции-члены. только свободные функции (в т.ч. friend функции)


Получается, компилятор видит что имя зависимо, откладывает поиск до инстанцирования, а при инстанцировании видит что func это член, для функций-членов ADL не проводится, и не находит его.
Правильно я понимаю?
Re: Зависимые имена в шаблонах
От: k.o. Россия  
Дата: 20.10.13 10:41
Оценка: 11 (2)
Здравствуйте, seejay, Вы писали:

S>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?


стандарта C++11 под рукой нет, но в C++2003 согласно 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.

Re[4]: Зависимые имена в шаблонах
От: k.o. Россия  
Дата: 20.10.13 11:11
Оценка:
Здравствуйте, Abyx, Вы писали:

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


A>проблема в том, что С это зависимый тип, и у него может быть специализация без func().

A>по этому компилятор не ищет имена в зависимых базовых типах.

А если написать this->func(), то это поможет если у C будет специализация без func()?
Re[5]: Зависимые имена в шаблонах
От: Abyx Россия  
Дата: 20.10.13 11:47
Оценка: :)
Здравствуйте, k.o., Вы писали:

A>>проблема в том, что С это зависимый тип, и у него может быть специализация без func().

A>>по этому компилятор не ищет имена в зависимых базовых типах.

KO>А если написать this->func(), то это поможет если у C будет специализация без func()?


да, ошибка изменится.
In Zen We Trust
Re[2]: Зависимые имена в шаблонах
От: seejay Россия  
Дата: 20.10.13 11:55
Оценка:
Здравствуйте, k.o., Вы писали:

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


S>>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?


KO>стандарта C++11 под рукой нет, но в C++2003 согласно 14.6.2/3, имена из базового класса не используются, как в точке определения шаблона, так и в точке инстанцирования.


KO>

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


Спасибо. Теперь понял.
Re[2]: Зависимые имена в шаблонах
От: rg45 СССР  
Дата: 21.10.13 14:02
Оценка:
Здравствуйте, k.o., Вы писали:

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


S>>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?


KO>стандарта C++11 под рукой нет, но в C++2003 согласно 14.6.2/3, имена из базового класса не используются, как в точке определения шаблона, так и в точке инстанцирования.


KO>

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


Хочу дополнить. Иногда полезно явно внести имя из базового класса в производный при помощи using-объявления. После этого это имя начинает участвовать в выборе кандидатов на подстановку:
template<typename T>
class Base
{
public:
  void foo();
};

template<typename T>
class Derived : public Base<T>
{
public:

  using Base::foo;

  void bar() { foo(); }
};
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.