#c #visual-studio-2015 #visual-studio-2019 #friend
Вопрос:
Следующее простое приложение демонстрирует ошибку компиляции:
Объявление моего класса: MyClass.h
#pragma once
class MyClass
{
friend int MyCalc();
public:
};
определение класса: MyClass.cpp
#include "stdafx.h"
#include "MyClass.h"
int MyCalc()
{
return 1 2;
}
Основная функция: ConsoleApplication1.cpp
#include "stdafx.h"
#include "MyClass.h"
#include <iostream>
int main()
{
std::cout << MyCalc();//"Identifier MyCalc is undefined" in Visual Studio 2019, but not in 2015
return 0;
}
Я предполагаю, что обновленная версия c сделала это более строгим.
Так что мне придется добавлять объявление функции за пределами класса везде, где у меня объявлена функция друга, например так:
class MyClass
{
friend int MyCalc();
public:
};
int MyCalc();
Комментарии:
1. C был таким уже долгое время.
2. В компиляторе Visual Studio C были ошибки, которые были исправлены в 2019 году.
3. Попробуйте отключить предварительно скомпилированные заголовки. Они вам не нужны для небольших программ.
4. Текущая настройка C/C = «Не использовать предварительно скомпилированные заголовки»
Ответ №1:
Это предложение, найденное в [namespace.memdef]
, из-за которого имя MyCalc()
не может быть найдено внутри main()
, и оно было частью стандарта C до тех пор, пока существовал стандарт C .
Каждое имя, впервые объявленное в пространстве имен, является членом этого пространства имен. Если объявление друга в нелокальном классе сначала объявляет класс или функцию, класс или функция друга является членом самого внутреннего заключительного пространства имен. Имя друга не будет найдено простым поиском по имени до тех пор, пока в этой области пространства имен не будет предоставлено соответствующее объявление (либо до, либо после объявления класса, предоставляющего дружбу).
Более старые версии компилятора Visual C , возможно, неправильно применяли это правило, но ваш код ошибочен и всегда был ошибочным, и Visual Studio 2019 правильно сообщает вам об этом.
Комментарии:
1. Я был бы признателен, если бы кто-нибудь проверил это правило в C 98.
2. Та же формулировка содержится в C 98 (раздел 7.3.1.2, пункт 3).