Используемая нами внешняя библиотека содержит следующий явный конструктор:
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
не имеет смысла в этом случае в любом случае. Кто-нибудь может подтвердить?
Лучшая ставка на милю страны — отключить это предупреждение на время включения, если вы понимаете мое значение. не взломать код поставщика.
С помощью explicit
для конструкторов с несколькими аргументами имеет смысл в C ++ 11 и далее, поскольку он может использоваться для остановки неявной инициализации фигурной скобки. Далее стандарт не говорят, что удаление explicit
должен сохранить расположение класса, так что вы должны предположить, что удаление explicit
мог нарушить бинарную совместимость Кроме того, сбросив его мог измените поведение надуманных шаблонов SFINAE, так как этот конструктор может стать доступным при определенных обстоятельствах. Увидеть http://en.cppreference.com/w/cpp/language/sfinae.
explicit
имеет смысл с несколькими параметрами в контексте инициализаторов скобок в C ++ 11 и выше:
void foo(Chart const &);
// ...
// Will only compile without `explicit`
foo({Chart::Type::pie, myObj});
Является ли это двоично-совместимым, чтобы удалить explicit
в конечном итоге зависит от вашего компилятора, так что вы должны найти это в его документации.
Тем не менее, так как explicit
это языковая функция высокого уровня, которая управляет только разрешением перегрузки, я не ожидаю, что она нарушит совместимость до тех пор, пока это не изменит то, что лучше всего подходит для какого-то уже существующего вызова, в том числе внутри любого кода, который вы компилируете из самой библиотеки (шаблоны и / или встроенные функции).
Тем не менее, это чистое специальное исправление: в соответствии со Стандартом, это приводит вас прямо на территорию UB. Цитировать из Н.М.комментарий:
Подобные заголовки нарушают ODR. Двоичные файлы поставщика скомпилированы с определенным определением класса, ваши двоичные файлы скомпилированы с другим определением того же класса. Это незаконно. Неважно, насколько мало изменение. Определения должны быть идентичны токену, точка.
Я бы рекомендовал просто замолчать предупреждение в этих заголовках, обернув их в #pragma
s где включено (или в пользовательском заголовке прокси, и включите это).