我正在使用优秀的ApprovalTests.cpp库编写批准测试。该库自动生成函数结果的“快照”。T
使用ostream& operator<< (T val)
. _
此运算符一直是用于将某些值格式化为文本表示的 C++ 约定。虽然原始类型支持此运算符并且您可以为自定义类型编写自己的实现,但对于 STL 容器(如std::vector
.
您可以实现自己的,甚至使用其他库,如fmt
or pprint
。以下是一些具有类似输出的示例。我使用泛型类型STREAM
作为参数,而不是ApprovalTests.cpp 推荐ostream
的具体类型,但这个想法没有改变。
for 循环
template <typename STREAM, typename T> STREAM& operator<<(STREAM& os, const std::vector<T>& vec) {
os << "[";
for (const auto& x : vec) {
os << x << ", ";
}
os << "]";
return os;
}
ostream_iterator
template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
using namespace std;
os << "[";
copy(v.begin(), v.end(), ostream_iterator<T>(os, ", "));
os << "]";
return os;
}
fmt
template <typename STREAM, typename T> STREAM& operator<<(STREAM& os, const std::vector<T>& vec) {
fmt::print(os, "[{}]", fmt::join(vec, ", "));
return os;
}
带<fmt/ranges.h
标题:
template <typename STREAM, typename T> STREAM& operator<<(STREAM& os, const std::vector<T>& vec) {
fmt::print(os, "{}", vec);
return os;
}
漂亮的印刷品
https://github.com/p-ranav/pprint
template <typename STREAM, typename T> STREAM& operator<<(STREAM& os, const std::vector<T>& vec) {
pprint::PrettyPrinter printer{os};
printer.print(vec);
return os;
}
cxx-prettyprint
只需包含prettyprint.hpp,它就适用于 STL 容器。
这似乎是最简单的解决方案,但与其他解决方案有相同的问题,它可能会破坏其他代码。
大会?
在对 Rust 有一些经验之后,我发现对每个 C++ STL 容器都这样做很乏味。这样做可能会破坏其他代码,例如,相同的运算符已为向量重载。
在 Rust 中,您只需将#[Debug]
要struct
格式化的文本添加到文本中,它就可以自动转换为文本表示形式,或者如果您需要一些非规范表示形式,您可以自己实现特征。结构作者有责任定义其Debug
实现。这就是为什么 Rust 标准库中的每个容器都有自己的Debug
实现。
我在问 C++ 中是否存在一些约定,或者有一些类似的标准提案。它可能对批准测试很有用,比如在我的例子中,但也适用于日志记录或调试(调试器可以使用此格式化程序向用户显示变量值)。