Информация об изменениях

Сообщение Re: Using - это сильный typedef или такой как и раньше? от 27.05.2022 19:37

Изменено 27.05.2022 20:12 rg45

Re: Using - это сильный typedef или такой как и раньше?
Здравствуйте, Marty, Вы писали:

M>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?


Не просто одинаковыми, а идентичными Т.е. это просто один и тот же тип.

Я даже больше скажу, при вызове функции без использования явной квалификации пространства имен, активируется ADL (Argument Dependent Lookup). Так вот, ADL будет искать кандидата на подстановку в том, пространстве имен, где определен реальный тип (в случае UDT), а в пространство имен, где определен алиас, даже не заглянет. Это такие грабли, про которые многи постоянно забывают, почему-то. Ниже иллюстрация:

http://coliru.stacked-crooked.com/a/e3c84cee78545253

#include <iostream>

namespace ns1 {

struct A {};

void foo(const A&) { std::cout << 1 << std::endl; }

}

namespace ns2 {

using B = ns1::A;

void foo(const B&) { std::cout << 2 << std::endl; }

}


int main()
{
    const ns1::A a;
    const ns2::B b;

    foo(a); // --> 1
    foo(b); // --> 1 again, not 2!
}
Re: Using - это сильный typedef или такой как и раньше?
Здравствуйте, Marty, Вы писали:

M>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?


Не просто одинаковыми, а идентичными Т.е. это просто один и тот же тип.

Я даже больше скажу, при вызове функции без использования явной квалификации пространства имен, активируется ADL (Argument Dependent Lookup). Так вот, ADL будет искать кандидата на подстановку в том пространстве имен, где определен реальный тип (в случае UDT), а в пространство имен, где определен алиас, даже не заглянет. Это такие грабли, про которые многие постоянно забывают, почему-то. Ниже иллюстрация:

http://coliru.stacked-crooked.com/a/e3c84cee78545253

#include <iostream>

namespace ns1 {

struct A {};

void foo(const A&) { std::cout << 1 << std::endl; }

}

namespace ns2 {

using B = ns1::A;

void foo(const B&) { std::cout << 2 << std::endl; }

}


int main()
{
    const ns1::A a;
    const ns2::B b;

    foo(a); // --> 1
    foo(b); // --> 1 again, not 2!
}