Я использую G ++ в основном и в настоящее время Visual Studio 2015.
Я хотел построить свой проект с VC ++ 2015, но я получаю сообщения об ошибках, в которых говорится о недопустимом использовании ‘::’ в функции с заданными аргументами по умолчанию и объявленным строго типизированным перечислением.
Вот некоторый код:
struct Foo
{
//! Forward declaration of Bar
enum class Bar : short;
//! "Faulty" function with default argument
void DoSmth(Bar aBar = Bar::Baz)
{
// ... code ...
}
//! Complete declaration of Bar
enum class Bar : short
{
Baz
};
};
int main() { }
Это дает мне следующую ошибку при объявлении функции DoSmth () с аргументом по умолчанию Bar :: Baz:
test.cpp(7): error C2589: '::': illegal token on right side of '::'
test.cpp(7): error C2059: syntax error: '::'
test.cpp(17): fatal error C1903: unable to recover from previous error(s); stopping compilation
С G ++ (протестировано с 4.9 и 5.1) код компилируется просто отлично, но с VC ++ 2015 это не так.
Я полностью осознаю, что я должен объявить что-то перед использованием, но.
Не потому ли, что VC ++ 2015 не ищет в рамках класса полное объявление и определение Bar, а G ++ делает это?
Или, может быть, G ++ просто берет полное объявление и «сливает» его с предварительным объявлением (так как они находятся в одной области видимости) и таким образом делает его полностью доступным для класса?
Или, может быть, я просто ошибаюсь и что-то совершенно другое вызывает это?
Я могу с этим смириться, что мне нужно изменить все мои объявления для строго типизированных перечислений, чтобы он работал с VC ++ 2015.
Но я также хочу знать, почему это так?
Ваш код действителен, а VC 14 неправильно, чтобы отклонить его.
В соответствии с N4527, Текущий Стандарт рабочего проекта, [9.2p2]:
Класс считается полностью определенным типом объекта (3.9) (или
полный тип) при закрытии}
из класса спецификатор. В пределах
учебный класс член-спецификация, класс считается завершенным в течение
тела функций, аргументы по умолчанию, с помощью деклараций введения
наследующие конструкторы (12.9), исключение-технические характеристики, а также
скобки или равно-инициализаторы для нестатических членов данных (в том числе
такие вещи во вложенных классах). В противном случае он считается неполным
в своем собственном классе член-спецификация.
В аргументе по умолчанию поиск Bar::Baz
требует полного определения Bar
, который доступен в полном классе, так что все в порядке.
Может быть, временное решение — это перенести полное определение enum class
быть до вызова функции DoSmith()
,