У меня есть этот код:
#include <array>
#include <iostream>
class ExternalGeometryExtension
{
public:
enum Flag {
Defining = 0,
Frozen = 1,
Detached = 2,
Missing = 3,
Sync = 4,
NumFlags
};
constexpr static std::array<const char *,NumFlags> flag2str{{ "Defining", "Frozen", "Detached","Missing", "Sync" }};
};
int main()
{
std::cout << ExternalGeometryExtension::flag2str[ExternalGeometryExtension::Frozen] << std::endl;
return 0;
}
Он отлично компилируется с: clang версии 5.0.0 и gcc (Убунту 4.8.4-2Убунту1~14.04.3) 4.8.4
Не удается скомпилировать с MSVC2013.
Ошибка компиляции:
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2144: syntax error : 'int' should be preceded by ';' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2146: syntax error : missing ';' before identifier 'flag2str' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2838: 'array<char const *,5>' : illegal qualified name in member declaration [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2143: syntax error : missing ';' before '{' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2334: unexpected token(s) preceding '{'; skipping apparent function body [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod\Sketcher\App\ExternalGeometryExtension.cpp(36): error C2143: syntax error : missing ';' before 'std::array<const char *,0x05>' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod\Sketcher\App\ExternalGeometryExtension.cpp(36): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod\Sketcher\App\ExternalGeometryExtension.cpp(36): error C2039: 'flag2str' : is not a member of 'Sketcher::ExternalGeometryExtension' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C2144: syntax error : 'int' should be preceded by ';' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C2146: syntax error : missing ';' before identifier 'flag2str' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C2838: 'array<char const *,5>' : illegal qualified name in member declaration [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C2143: syntax error : missing ';' before '{' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
c:\projects\freecad\src\mod\sketcher\app\ExternalGeometryExtension.h(47): error C2334: unexpected token(s) preceding '{'; skipping apparent function body [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2144: syntax error : 'int' should be preceded by ';' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2146: syntax error : missing ';' before identifier 'flag2str' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2838: 'array<char const *,5>' : illegal qualified name in member declaration [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2143: syntax error : missing ';' before '{' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod/Sketcher/App/ExternalGeometryExtension.h(47): error C2334: unexpected token(s) preceding '{'; skipping apparent function body [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
C:\projects\freecad\src\Mod\Sketcher\App\ExternalGeometryExtensionPyImp.cpp(67): error C2039: 'flag2str' : is not a member of 'Sketcher::ExternalGeometryExtension' [C:\projects\freecad\build\src\Mod\Sketcher\App\Sketcher.vcxproj]
Полный вывод компилятора здесь
Мои вопросы: Что я делаю неправильно? Почему не компилируется с MSVC2013?
Могу ли я что-то сделать, чтобы этот код работал с MSVC2013, не нарушая его в других компиляторах?
Обновлено: я изменил код, чтобы он был минимальным, полным и проверяемым примером, как запросил Тоби Спейт, основываясь на правильном предположении Диодака. Я не могу вывести ошибку этого конкретного кода, потому что у меня нет копии MSVC2003. Я работаю над FreeCAD с открытым исходным кодом, который предлагает поддержку Windows. Я использую линукс. В любом случае ошибки в выводе соответствуют коду, который я показываю. Это результат теста AppVeyor перед интеграцией. Код отлично проходит Linux CI. Я постараюсь максимально использовать этот вопрос, надеясь, что он будет полезен для других.
Обновлено еще раз: я понял, что инициализация двойной скобки вызвала некоторые удивления. Из примера в cppreference:
double-braces required in C++11 prior to the CWG 1270 revision (not needed in C++11 after the revision and in C++14 and beyond)
Без двойных скобок gcc 4.8 не работает.
Как ежедневный пользователь VS2013, я знаю только два варианта: запретить «новые» стильные функции C++ или #ifdef альтернативный код, совместимый с VS2013. Оба варианта неудовлетворительны... ;-)
В коде, который вы показываете, нет даже имеют 36 строк, поэтому эти сообщения об ошибках не могли исходить от него. Пожалуйста, включите сообщения об ошибках минимальный воспроизводимый пример и соответствующий.
@Scheff Вы ответили на последний вопрос. Я думал об этом варианте. Как вы указываете, это неудовлетворительно. Я, вероятно, отброшу constexpr и перенесу определение за пределы класса. Спасибо вам.
@Toby Speight Я отредактировал вопрос, чтобы сделать полностью рабочий пример с помощью Диодака. Как я указываю сейчас в вопросе, у меня нет доступа к фактическим сообщениям об ошибках этого сокращенного примера. Спасибо за указание на это.





Согласно этому блог разработчиков Майкрософт, constexpr является одной из основных функций языка С++ 11, которая не поддерживается в VS 2013. И только частично поддерживается в CTP за ноябрь 2013 г.
Да, это отвечает на мой вопрос. Код совместим с C++11, но MSVC2013 не поддерживает полный стандарт. Я не смог найти этот ответ самостоятельно. Спасибо большое.
Что ж, рассматриваемый код компилируется с опцией С++ 17:
#include <array>
#include <iostream>
class ExternalGeometryExtension
{
public:
enum Flag {
Defining = 0,
Frozen = 1,
Detached = 2,
Missing = 3,
Sync = 4,
NumFlags
};
constexpr static std::array<const char *,NumFlags> flag2str{{ "Defining", "Frozen", "Detached","Missing", "Sync" }};
};
int main()
{
std::cout << ExternalGeometryExtension::flag2str[ExternalGeometryExtension::Frozen] << std::endl;
return 0;
}
И нет необходимости повторно объявлять статическую переменную вне класса.
@Abdullah Tahiri Пожалуйста, используйте конструкции С++ 11 (как указано в вопросительных метках) или перейдите на С++ 17 для всех функций. Но я боюсь, что MSVC может вызвать проблемы с кодом. Есть ли какая-то особая причина, по которой вы не можете использовать GCC или CLang в Windows?
Спасибо за очистку/дополнение кода. Я использовал ваш пример в вопросе, чтобы он был понятен в будущем. Я думаю, что все мои конструкции соответствуют стандарту С++ 11. Отвечая на ваш вопрос, этот код предназначен для относительно большого проекта FreeCAD, который в настоящее время использует MSVC2013 для создания сборок Windows. У меня нет машины с Windows. Я не знаю, почему мы используем MSVC2013, но я использую ваш вклад, чтобы спросить ответственного лица. Спасибо.
MSVC2013 устарел. И его поддержка С++ 11 была неполной. До недавнего времени у MS действительно не было приличного компилятора для C++11.