C++ 11 Расширенные friend объявления

class C;
typedef C Ct;
 
class X1
{
    friend C; // OK: class C is a friend
};
 
class X2
{
    friend Ct; // OK: class C is a friend
    //friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-specifier declares new class
};
 
template <typename T> class R
{
    friend T;
};
 
 
int main(void)
{
    R<C> rc; // class C is a friend of R<C>
    R<int> Ri; // OK: “friend int;” is ignored
 
    return 0;
}

Изучаю стандарт С++11 по документу:

https://ru.cppreference.com/w/cpp/compiler_support/11

В частности мой вопрос описан здесь:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf

Код, который я предоставил выше, работает на VS2005 и на VS2019 - компилируется без ошибок.

Не пойму, что значит это исправление в C++11 "Расширенные friend объявления" - если код работает на старых VS, то не понятно, что там изменилось.

Объясните, пожалуйста, простыми словами принцип этого изменения C++11 "Расширенные friend объявления".


Ответы (1 шт):

Автор решения: user7860670

В стандарте C++03 при объявлении дружеского типа должен был указываться elaborated-type-specifier c обязательным явным указанием class-key (class struct union). т.е. разрешалось только:

class X1
{
    friend class C;
};

В С++11 это требование смягчили, разрешив указывать там произвольное имя типа, а т.ч. имя параметра шаблона. На тот момент это уже была распространенная практика среди компиляторов, а Visual С++ не отличался четким следованием букве стандарта. Да и gcc при сборке по стандарту С++03 по-умочанию не жалуется, надо явно указывть -Wpedantic.

→ Ссылка