"Нет подходящего конструктора для инициализации" 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 означает, что синтаксис вашего макроса не должен изменяться: вместо фигурных скобок, означающих список значений для отдельных элементов, фигурные скобки будут означать список параметров для конструктора, но результат будет таким же,

Другие вопросы по тегам