2

首先,我目前正在为我的论文学习 C++,因此对这门语言缺乏经验。任何帮助表示赞赏。

我在我的代码中使用 fmt 库,并且可以格式化用户提供的类型的规范方式是通过专门化类模板类型fmt::formatter

例子

编译器资源管理器中的代码:https ://godbolt.org/z/2VO_wa

给定两个库Aand 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());

LibraryA使用与 不同的实现B,因为它考虑了本地时区而不是在 UTC 中打印。

现在这个例子非常具体,但由于类模板fmt::formatter是格式化用户提供的类型的方法,这种情况可能会以一种或另一种形式发生。

问题

当我开发我的应用程序C并使用两个(不相关的)库时AB我相信会有两个相同类型(即fmt::formatter<std::chrono::system_clock::time_point>)的不同实现,从而违反未定义行为的 ODR。

问题

假设我正确理解了情况,我的两个问题是:

  1. C有没有办法在不改变AB上游的情况下避免应用程序中的这种冲突?
  2. 如果可以修改其中一个AB(或两者),可以通过什么方式解决或完全防止冲突。
4

1 回答 1

4
  1. 有没有办法在不改变上游 A 和 B 的情况下避免应用程序 C 中的这种冲突?

您确实违反了 ODR,我认为您无法在不更改 A 和/或 B 的情况下避免冲突。

  1. 如果可以修改 A 或 B(或两者),可以通过哪些方式解决或完全防止冲突。

仅专门化您自己的库的类型:因此在库 A 中,创建包装器std::chrono::system_clock::time_point

 namespace A {
     struct TimePoint {
         std::chrono::system_clock::time_point timePoint;
     };
 }


namespace fmt {
     // Specialization of formatter<TimePoint>
}

接着

auto msg = fmt::format("It is now {}", A::TimePoint{std::chrono::system_clock::now()});

图书馆 B 也一样。

于 2018-10-29T22:50:13.740 回答