Во-первых, я сейчас изучаю C ++ для своей диссертации и поэтому не знаю языка. Любая помощь приветствуется.
Я использую библиотеку fmt в своем коде, и канонический способ форматирования предоставленных пользователем типов заключается в специализации типа шаблона класса fmt::formatter
.
Пример
Код в проводнике компилятора: https://godbolt.org/z/2VO_wa
Имеются две библиотеки A
и B
, которые обе часто используют fmt в своей реализации, и обе они так или иначе нуждаются в печати / протоколировании текущего времени.
Оба могут разумно использовать std::chrono::system_clock
, и, желая отформатировать его в нескольких точках, каждый определяет свою собственную версию fmt::formatter<std::chrono::system_clock::time_point>
, чтобы сделать этот простой код возможным:
auto msg = fmt::format("It is now {}", std::chrono::system_clock::now());
Библиотека A
использует реализацию, отличную от B
, поскольку вместо печати в формате UTC учитывается местный часовой пояс.
Теперь этот пример очень специфичен, но поскольку шаблон класса fmt::formatter
- это способ форматирования пользовательских типов, этот сценарий может происходить в той или иной форме.
Проблема
Когда я разрабатываю свое приложение C
и использую обе (не связанные) библиотеки A
и B
, тогда я полагаю, что будут две разные реализации одного и того же типа (а именно fmt::formatter<std::chrono::system_clock::time_point>
), таким образом нарушая ODR с неопределенным поведение.
Вопрос
Если я правильно понимаю ситуацию, у меня два вопроса:
- Есть ли способ избежать этого конфликта в приложении
C
без изменения A
и B
upstream?
- Если можно изменить
A
или B
(или оба), каким образом конфликт может быть разрешен или полностью предотвращен.