Недавно я изучил точное значение известного «двухфазного поиска имени» для имен в классах шаблонов. Хотя я прочитал много статей об этом, я все еще не могу все знать об этом. Теперь я запутался в коде, показанном ниже:Странное поведение при поиске зависимого от аргумента имени в шаблоне
template<typename T>
class A
{
public:
void f(T, T){};
};
namespace ns
{
typedef int TT;
void f(int, int){};
};
template<typename T>
class B : public A<T>
{
public:
void g()
{
//f(T(), T()); // it's fine for error here
typedef ns::TT TTT;
f(TTT(), T()); // why this issued an error?
f(ns::TT(), T()); // and this?
}
};
/* I also think it's OK to move ns here */
// namespace ns
// {
// typedef int TT;
// void f(int, int){};
//};
int main()
{
B<int> b;
b.g();
}
Обратите внимание на второй комментарий. Поскольку «f» является зависимым именем, его поиск должен задерживаться до момента создания в «основной» функции. И в это время компилятор должен выполнить зависящий от аргумента поиск имени в области основной функции. Я думаю, что теперь он должен открыть эту функцию в пространстве имен нс, но она по-прежнему выдается ошибка компиляции:
1.cpp: In instantiation of 'void B<T>::g() [with T = int]':
1.cpp:30:6: required from here
1.cpp:23:15: error: 'f' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] f(TTT(), T()); //why this issued an error?
^
1.cpp:23:15: note: declarations in dependent base 'A<int>' are not found by unqualified lookup
1.cpp:23:15: note: use 'this->f' instead
Может кто-нибудь объяснить мне это? Благодарю.
[basic.lookup.argdep]/2 «для каждого типа аргумента' T' в вызове функции, существует набор из нуля или более связанных с пространствами имен, и множество нулевого или более связанных классов. Множества пространств имен и классов определяются полностью типами аргументов функции (и пространства имен любого аргумента шаблона шаблона). ** Названия Typedef и используемые декларации, используемые для указания типы не вносят свой вклад в этот набор. ** «[акцент мой] Я не думаю, что эта проблема связана с шаблонами. – dyp
А как насчет ошибки при третьем комментарии? f (ns :: TT(), T())? – sunlight07
Ну 'ns :: TT' - это typedef для' int'. И 'ns' не является ассоциированным пространством имен' int'. Это же правило применяется. (Присутствие 'ns ::' просто изменяет поиск имени для 'TT', следуя за' :: ', это не изменяет поиск имени' f' - это все еще зависит только от типов аргументов.) – dyp