如何为Googletest实现无UB的std::future_status自定义值打印器?
为std::future_status实现无UB的Googletest值打印器
你可以通过两种完全符合C++标准、无未定义行为的方式实现,不需要扩展std命名空间:
方案1:自定义包装器 + PrintTo 重载
先写一个轻量包装结构体,把std::future_status包起来,然后给这个自定义类型实现Googletest的PrintTo函数:
#include <future> #include <gtest/gtest.h> struct FutureStatusWrap { std::future_status val; explicit FutureStatusWrap(std::future_status s) : val(s) {} }; // 全局命名空间下实现PrintTo,完全合法 void PrintTo(const FutureStatusWrap& wrap, std::ostream* os) { switch (wrap.val) { case std::future_status::ready: *os << "std::future_status::ready"; break; case std::future_status::timeout: *os << "std::future_status::timeout"; break; case std::future_status::deferred: *os << "std::future_status::deferred"; break; default: *os << "std::future_status::unknown(" << static_cast<int>(wrap.val) << ")"; } } // 辅助函数简化包装 inline FutureStatusWrap wrap_fs(std::future_status s) { return FutureStatusWrap(s); }
测试代码只需把枚举值包装后再断言:
TEST(setup_test_case, testWillPass) { auto a = std::future_status::ready; auto b = std::future_status::timeout; EXPECT_EQ(wrap_fs(a), wrap_fs(b)); }
断言失败时,会输出清晰的枚举名称,而非默认的数字值。
方案2:重载testing::internal::PrintToString
Googletest内部会用testing::internal::PrintToString生成对象的字符串表示,你可以在这个命名空间下重载该函数处理std::future_status——这属于Googletest官方允许的扩展方式,完全无UB:
#include <future> #include <gtest/gtest.h> #include <string> namespace testing::internal { std::string PrintToString(std::future_status status) { switch (status) { case std::future_status::ready: return "std::future_status::ready"; case std::future_status::timeout: return "std::future_status::timeout"; case std::future_status::deferred: return "std::future_status::deferred"; default: return "std::future_status::unknown(" + std::to_string(static_cast<int>(status)) + ")"; } } } // namespace testing::internal
这种方案不需要修改原有测试代码,原有的EXPECT_EQ(a, b)会自动使用你的打印逻辑,错误信息直接显示枚举名称,是最简洁的实现方式。
为什么这两种方案都安全?
- 方案1的包装器是自定义类型,在全局命名空间实现
PrintTo完全符合C++标准,没有触碰std命名空间。 - 方案2是在Googletest提供的
testing::internal扩展命名空间内添加函数,不属于扩展std的行为,完全符合标准要求,也符合Googletest的设计意图。
内容的提问来源于stack exchange,提问作者Sir l33tname
相关产品推荐
相关产品推荐

