{fmt} 中基于特征的定制点和 ODR 违规问题
Trait based customisation points and ODR-violation concerns in {fmt}
首先,我目前正在为我的论文学习 C++,因此对这门语言没有经验。感谢任何帮助。
我在我的代码中使用 fmt 库,格式化用户提供的类型的规范方式是通过专门化 class 模板类型 fmt::formatter
.
例子
编译器资源管理器中的代码:https://godbolt.org/z/2VO_wa
给定两个库 A
和 B
,这两个库恰好在其实现中大量使用 fmt 并且都以某种方式或其他方式需要 print/log 当前时间。
两者都可能合理地使用 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 打印。
现在这个例子非常具体,但是由于 class 模板 fmt::formatter
是格式化用户提供的类型的方式,所以这种情况可能以一种或另一种形式出现。
问题
当我开发我的应用程序 C
并同时使用(不相关的)库 A
和 B
时,我相信会有两个相同类型的不同实现(即 fmt::formatter<std::chrono::system_clock::time_point>
) 因此违反了具有未定义行为的 ODR。
问题
假设我理解正确,我的两个问题是:
- 有没有办法在不改变
A
和 B
上游的情况下避免应用程序 C
中的这种冲突?
- 如果可以修改
A
或 B
(或两者),则可以通过哪些方式解决或完全避免冲突。
- Is there a way to avoid this conflict in the application C without altering A and B upstream?
你确实违反了ODR,我认为你不改变A就可以避免冲突and/or B.
- If either A or B (or both) can be modified, in what ways can the conflict be resolved or fully prevented.
仅专门化您自己的库的类型:
所以在库 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 也一样。
首先,我目前正在为我的论文学习 C++,因此对这门语言没有经验。感谢任何帮助。
我在我的代码中使用 fmt 库,格式化用户提供的类型的规范方式是通过专门化 class 模板类型 fmt::formatter
.
例子
编译器资源管理器中的代码:https://godbolt.org/z/2VO_wa
给定两个库 A
和 B
,这两个库恰好在其实现中大量使用 fmt 并且都以某种方式或其他方式需要 print/log 当前时间。
两者都可能合理地使用 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 打印。
现在这个例子非常具体,但是由于 class 模板 fmt::formatter
是格式化用户提供的类型的方式,所以这种情况可能以一种或另一种形式出现。
问题
当我开发我的应用程序 C
并同时使用(不相关的)库 A
和 B
时,我相信会有两个相同类型的不同实现(即 fmt::formatter<std::chrono::system_clock::time_point>
) 因此违反了具有未定义行为的 ODR。
问题
假设我理解正确,我的两个问题是:
- 有没有办法在不改变
A
和B
上游的情况下避免应用程序C
中的这种冲突? - 如果可以修改
A
或B
(或两者),则可以通过哪些方式解决或完全避免冲突。
- Is there a way to avoid this conflict in the application C without altering A and B upstream?
你确实违反了ODR,我认为你不改变A就可以避免冲突and/or B.
- If either A or B (or both) can be modified, in what ways can the conflict be resolved or fully prevented.
仅专门化您自己的库的类型:
所以在库 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 也一样。