Почему имя 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;
}
Здравствуйте, seejay, Вы писали:
S>Почему имя func не находится? Оно зависимо, т.к. параметр pt зависим. Обычный поиск его не найдет, что естественно. Почему оно не находится во время инстанцирования?
Здравствуйте, 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 должен найти, вроде бы, по параметру, но не находит.
Здравствуйте, seejay, Вы писали:
S>Вопрос в другом. Почему без дополнительных квалификаторов это имя не может быть найдено? S>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое. ADL должен найти, вроде бы, по параметру, но не находит.
проблема в том, что С это зависимый тип, и у него может быть специализация без func().
по этому компилятор не ищет имена в зависимых базовых типах.
Тут вы не правы, функция с параметрами зависящими от параметра шаблона — это зависимое имя.
Например, если закоментировать вызов 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;
}
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, seejay, Вы писали:
S>>Вопрос в другом. Почему без дополнительных квалификаторов это имя не может быть найдено? S>>Есть зависимый базовый класс. Поиск независимых имен в нем не проводится, но func — имя зависимое. ADL должен найти, вроде бы, по параметру, но не находит. A>проблема в том, что С это зависимый тип, и у него может быть специализация без func(). A>по этому компилятор не ищет имена в зависимых базовых типах.
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, seejay, Вы писали:
S>>ADL должен найти, вроде бы, по параметру, но не находит.
A>так ADL вроде не ищет функции-члены. только свободные функции (в т.ч. friend функции)
Получается, компилятор видит что имя зависимо, откладывает поиск до инстанцирования, а при инстанцировании видит что func это член, для функций-членов ADL не проводится, и не находит его.
Правильно я понимаю?
Здравствуйте, 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.
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, seejay, Вы писали:
A>проблема в том, что С это зависимый тип, и у него может быть специализация без func(). A>по этому компилятор не ищет имена в зависимых базовых типах.
А если написать this->func(), то это поможет если у C будет специализация без func()?
Здравствуйте, k.o., Вы писали:
A>>проблема в том, что С это зависимый тип, и у него может быть специализация без func(). A>>по этому компилятор не ищет имена в зависимых базовых типах.
KO>А если написать this->func(), то это поможет если у C будет специализация без func()?
Здравствуйте, 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.
Здравствуйте, 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(); }
};
--
Не можешь достичь желаемого — пожелай достигнутого.