首先,我目前正在为自己的论文学习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
时,我相信会有两个不同的相同类型的实现(即{{1} })从而违反了具有未定义行为的ODR。
假设我正确理解了情况,我的两个问题是:
fmt::formatter<std::chrono::system_clock::time_point>
中发生这种冲突,而又不改变上游的C
和A
?B
或A
(或两者)中的任何一个,则可以通过什么方式解决冲突或完全避免冲突。答案 0 :(得分:4)
- 是否有一种方法可以避免在应用程序C中发生这种冲突而又不改变上游的A和B?
您确实违反了ODR,我认为您必须在不更改A和/或B的情况下避免冲突。
- 如果可以修改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相同。