"Нет подходящего конструктора для инициализации" Rad Studio 10 Clang Compiler
У меня есть фрагмент кода, который компилируется в C++ Builder XE8 с использованием классического компилятора BCC. Однако в Rad Studio 10 Seattle с использованием компилятора Clang я получаю ошибку
'no matching constructor found for initialization of TChoiceItem'
Вот фрагмент кода, который вызывает ошибку.
LISTITEM_BEGIN( sch_TYPE_Choice )
LISTITEM_DATA( sch_TYPE_Daily, "Daily" )
LISTITEM_DATA( sch_TYPE_Weekly, "Weekly" )
LISTITEM_DATA( sch_TYPE_Monthly, "Monthly" )
LISTITEM_END()
Вот код, который определяет TChoiceItem
//------------------------------------------------------------------------------
#define LISTITEM_BEGIN( Name ) TChoiceItem Name[] = {
//------------------------------------------------------------------------------
#define INT_LISTITEM_BEGIN( Name ) TIntChoiceItem Name[] = {
//------------------------------------------------------------------------------
#define LISTITEM_DATA( XCode, XText ) { XCode, 0, (char*)XText, 0 },
#define LISTITEM_DATA_NC( XShortText, XText ) { 0, (char*)XShortText, (char*)XText, 0 },
#define LISTITEM_DATA_EX( XCode, XShortText, XText ) { XCode, (char*)XShortText, (char*)XText, 0 },
#define LISTITEM_DATA_EX2( XCode, XShortText, XText, XDesc ) { XCode, (char*)XShortText, (char*)XText, (char*)XDesc },
#define LISTITEM_END() LISTITEM_DATA(0,0) };
Я довольно новичок в C++, поэтому я не совсем уверен, что вызвать вышеупомянутый метод определения класса / метода.
Это какая-то особенность устаревшего языка не поддерживается компилятором Clang? Есть ли способ изменить код или определение, чтобы компилятор принял его?
Редактировать:
Я нашел фактическую декларацию TChoiceItem
учебный класс.
class TChoiceItem : public TChoiceBase
{
public:
char Code;
char *ShortText;
char *Text;
char *Desc;
};
Похоже, он не имеет никакого стандартного конструктора вообще. Но почему-то все по-прежнему компилируется и работает с классическим компилятором BCC.
Изменить 2:
Я нашел этот вопрос, который, похоже, описывает похожую проблему. Может быть, мне нужно включить какой-то флаг компилятора при компиляции кода? Если да, могу ли я как-нибудь добавить флаг в настройках компилятора проекта embarcadero?
1 ответ
Использование списка значений в фигурных скобках для инициализации отдельных членов класса или структуры называется агрегатной инициализацией.
Как объяснено на cppreference.com, агрегатная инициализация не разрешена, если у класса есть базовый класс (среди прочих ограничений). TChoiceItem
наследуется от TChoiceBase
Таким образом, агрегатная инициализация не разрешена (и "классический" компилятор bcc32 не должен был это разрешать).
У вас есть несколько вариантов:
Во-первых, вы можете изменить код, чтобы не наследовать от TChoiceBase
,
Во-вторых, вы можете определить конструктор:
TChoiceItem(char code, char *short_text, char *text, char *desc)
: Code(code), ShortText(short_text), Text(text), Desc(desc) {}
Равномерная инициализация в C++11 означает, что синтаксис вашего макроса не должен изменяться: вместо фигурных скобок, означающих список значений для отдельных элементов, фигурные скобки будут означать список параметров для конструктора, но результат будет таким же,