6 Aralık 2019 Cuma

Unqualified Name Lookup - Sınıf İsimlerine veya Sınıf İçindeki Alanlara Erişilmek İstenince Kullanılır

Giriş
Bu konu C++'taki bir çok lookup kavramlarından bir tanesi. Unqualified Name Lookup kavramı Argument Dependent Lookup kavramını içerir. Argument Dependent Lookup yazısına bakabilirsiniz. Unqualified Name Lookup yani UNL sınıf isimlerine veya sınıf içindeki alanlar erişilmek istenince kullanılır.

Unqualified denmesinin sebebi başına namespace veya global "::" operatörün konulmaması.

Açıklaması şöyle.
..., name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
Bu tür derleme hatalarından kurtulmak için sanırım her zaman fully qualified isimleri kullanmak lazım. Fully Qualified için tanım şöyle.
In computer programming, a fully qualified name is an unambiguous name that specifies which object, function, or variable a call refers to without regard to the context of the call
STL için açıklama şöyle.
Whenever a name x defined in the standard library is mentioned, the name x is assumed to be fully qualified as ::std::x, unless explicitly described otherwise. For example, if the Effects: element for library function F is described as calling library function G, the function ::std::G is meant.
Örnek
Template kodlarında ata sınıfa erişmek istediğimizi belirtmek gerekir. Açıklaması şöyle
At template definition time, you have no idea what the dependent base class is going to look like, thanks to specializations that may come in later, so you can't do any meaningful lookup. Every misspelled identifier in a template with a dependent base class can't be diagnosed until when it is instantiated, if ever. And since every unqualified identifier might have been from a dependent base class, you'll need some way to answer "is this a type?" and "is this a template?", since the answers to those questions affect parsing. That means something like the dreaded typename and template keywords, but in far more places.
Şu kod derlenmez. using T::x veya Base<T>::x şeklinde kullanırsak derlenir.
template<typename T>
class Base
{
public:
  T x;
};

template<typename T>
class C : public Base<T>
{
public:
  bool m() { return x == 0; } // Error: undeclared identifier 'x'
};
Örnek
Elimizde şöyle bir kod olsun. Burada Foo iki farklı yerde tanımlanıyor. Hem A namespace içinde hem de global namespace içinde. Bar içinde kullanmak istenince A namespace içindeki tercih ediliyor çünkü Bar sınıfı A::Foo'dan kalıtıyor.
namespace A {
  struct Foo {
    int a;
  };
}

struct Foo {
    int b;
};

struct Bar : public A::Foo {
  Bar(Foo foo) {
    c = foo.b; //compile error
  }
  int c;
};
Açıklaması şöyle.
Because unqualified name lookup of the argument type begins in the scope of the class Bar, it will continue into the scope of its base class to account for any member there. And it will find A::Foo::Foo as a type name.




Hiç yorum yok:

Yorum Gönder