在gtest的INSTANTIATE_TEST_SUITE_P宏中使用带结构化绑定的Lambda编译失败
在Google Test的INSTANTIATE_TEST_SUITE_P宏中直接使用带结构化绑定的Lambda的解决方案
问题重现
在使用Google Test的INSTANTIATE_TEST_SUITE_P宏时,直接传入包含结构化绑定的Lambda会触发编译失败,但以下两种方式可正常运行:
- 使用
std::get访问元组元素的Lambda:
using param = std::tuple<int, int>; // 可正常编译运行 INSTANTIATE_TEST_SUITE_P( instance, suite, cases, [](const testing::TestParamInfo<param>& info) { return std::to_string(std::get<0>(info.param)) + "_to_" + std::to_string(std::get<1>(info.param)); } );
- 将带结构化绑定的Lambda赋值给变量后传入宏:
// 可正常编译运行 static constexpr auto name_generator = [](const testing::TestParamInfo<param>& info) { const auto [a, b] = info.param; return std::to_string(a) + "_to_" + std::to_string(b); }; INSTANTIATE_TEST_SUITE_P( instance, suite, cases, name_generator );
- 直接传入带结构化绑定的Lambda则编译失败:
// 编译失败 INSTANTIATE_TEST_SUITE_P( instance, suite, cases, [](const testing::TestParamInfo<param>& info) { const auto [a, b] = info.param; return std::to_string(a) + "_to_" + std::to_string(b); } );
原因分析
问题根源在于C++预处理器的处理逻辑:INSTANTIATE_TEST_SUITE_P是宏定义,预处理器会将逗号视为宏参数的分隔符。当Lambda内部出现结构化绑定const auto [a, b] = info.param;时,[a, b]中的逗号会被预处理器误判为宏的第四个参数(Lambda起始部分)与第五个参数的分隔,导致宏参数数量不匹配,最终触发编译错误。
解决方案
方案1:将Lambda包裹在括号中
把整个Lambda表达式放在一对括号内,预处理器会将括号内的内容视为单个宏参数,不会拆分内部的逗号:
INSTANTIATE_TEST_SUITE_P( instance, suite, cases, ([](const testing::TestParamInfo<param>& info) { const auto [a, b] = info.param; return std::to_string(a) + "_to_" + std::to_string(b); }) );
方案2:用std::apply替代结构化绑定
借助std::apply访问元组元素,避免在Lambda内部出现逗号:
#include <tuple> INSTANTIATE_TEST_SUITE_P( instance, suite, cases, [](const testing::TestParamInfo<param>& info) { return std::apply([](int a, int b) { return std::to_string(a) + "_to_" + std::to_string(b); }, info.param); } );
方案3:将结构化绑定逻辑抽离到辅助函数
把包含结构化绑定的代码放到独立辅助函数中,Lambda仅调用该函数,避免在宏参数内出现逗号:
std::string generate_test_name(const param& param_tuple) { const auto [a, b] = param_tuple; return std::to_string(a) + "_to_" + std::to_string(b); } INSTANTIATE_TEST_SUITE_P( instance, suite, cases, [](const testing::TestParamInfo<param>& info) { return generate_test_name(info.param); } );
内容的提问来源于stack exchange,提问作者Dominik Kaszewski
相关产品推荐
相关产品推荐

