Совместимо ли удаление «явного» из двоичного конструктора?

Используемая нами внешняя библиотека содержит следующий явный конструктор:

class Chart {
public:
explicit Chart(Chart::Type type, Object *parent);
// ...
};

Компилятор жалуется со следующим предупреждением:

chart.h: warning #2305: declaration of 'explicit' constructor
without a single argument is redundant

Это бинарная совместимость, чтобы просто удалить explicit ключевое слово в chart.h без перекомпиляции библиотеки, чтобы избежать предупреждения? Я чувствую, что это безопасно, так как explicit не имеет смысла в этом случае в любом случае. Кто-нибудь может подтвердить?

9

Решение

Лучшая ставка на милю страны — отключить это предупреждение на время включения, если вы понимаете мое значение. не взломать код поставщика.

С помощью explicit для конструкторов с несколькими аргументами имеет смысл в C ++ 11 и далее, поскольку он может использоваться для остановки неявной инициализации фигурной скобки. Далее стандарт не говорят, что удаление explicit должен сохранить расположение класса, так что вы должны предположить, что удаление explicit мог нарушить бинарную совместимость Кроме того, сбросив его мог измените поведение надуманных шаблонов SFINAE, так как этот конструктор может стать доступным при определенных обстоятельствах. Увидеть http://en.cppreference.com/w/cpp/language/sfinae.

9

Другие решения

explicit имеет смысл с несколькими параметрами в контексте инициализаторов скобок в C ++ 11 и выше:

void foo(Chart const &);

// ...

// Will only compile without `explicit`
foo({Chart::Type::pie, myObj});

Является ли это двоично-совместимым, чтобы удалить explicit в конечном итоге зависит от вашего компилятора, так что вы должны найти это в его документации.

Тем не менее, так как explicit это языковая функция высокого уровня, которая управляет только разрешением перегрузки, я не ожидаю, что она нарушит совместимость до тех пор, пока это не изменит то, что лучше всего подходит для какого-то уже существующего вызова, в том числе внутри любого кода, который вы компилируете из самой библиотеки (шаблоны и / или встроенные функции).

Тем не менее, это чистое специальное исправление: в соответствии со Стандартом, это приводит вас прямо на территорию UB. Цитировать из Н.М.комментарий:

Подобные заголовки нарушают ODR. Двоичные файлы поставщика скомпилированы с определенным определением класса, ваши двоичные файлы скомпилированы с другим определением того же класса. Это незаконно. Неважно, насколько мало изменение. Определения должны быть идентичны токену, точка.

Я бы рекомендовал просто замолчать предупреждение в этих заголовках, обернув их в #pragmas где включено (или в пользовательском заголовке прокси, и включите это).

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector