Может ли дружественная функция локального класса быть определена в области пространства имен?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Может ли дружественная функция локального класса быть определена в области пространства имен?

Сообщение Anonymous »

Локальный класс в C++ может иметь дружественные функции, но эти функции не могут быть определены ни внутри класса [class.friend] p5:

Функция может быть определена в дружественном объявлении класса тогда и только тогда, когда класс является нелокальным классом и имя функции является неполным.

ни внутри включающей функции [dcl.fct.def.general] p2:

[...] Функция должна быть определена только в пространстве имен или области класса. [...]

А что, если дружественная функция локального класса определена в глобальной области следующим образом:

Код: Выделить всё

auto foo() {
struct A;
void bar(const A&);
struct A {
friend void bar(const A&);
};
bar(A{});
return A{};
}

using A = decltype(foo());
void bar(const A&) {}

int main() {
foo();
}
Здесь компиляторы расходятся:
  • MSVC показывает предупреждение о компиляции и завершается сбоем во время компоновки:

Код: Выделить всё

warning C5046: 'bar': Symbol involving type with internal linkage not defined
error LNK2019: unresolved external symbol "void __cdecl bar(struct `__cdecl foo(void)'::`2'::A const &)" (?bar@@YAXAEBUA@?1??foo@@YA@XZ@@Z) referenced in function "__cdecl foo(void)" (?foo@@YA@XZ)
  • EDG показывает ошибку компиляции:

Код: Выделить всё

error: function "bar", declared using a local type, must be defined in this translation unit
  • GCC уже принимает программу, но только с флагом -fpermissive, печатая предупреждение:

Код: Выделить всё

warning: 'void bar(const foo()::A&)', declared using local type 'const foo()::A', is used but never defined [-fpermissive]
  • и только Clang разрешает эту программу без единого предупреждения:
    онлайн-демо.
Какая реализация здесь правильная?


Подробнее здесь: https://stackoverflow.com/questions/769 ... pace-scope
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»