This may be related to How to correctly forward structured binding arguments in a macro , but I feel the real problem is not the same, so may have a different solution.
I want to pass a lambda as a name generator inside gtest's INSTANTIATE_TEST_SUITE_P. This works well until I try to use structured bindings, whose comma makes the preprocessor think it gets split into separate arguments.
using param = std::tuple<int, int>;
// This works
INSTANTIATE_TEST_SUITE_P(
instance, suite, cases,
[](const testing::TestParamInfo<param>& info) {
return std::string(std::get<0>(info.param)
+ "_to_" + std::string(std::get<1>(info.param));
}
);
// This also works
static constexpr auto name = [](const testing::TestParamInfo<param>& info) {
const auto [a, b] = info.param;
return std::string(a) + "_to_" + std::to_string(b);
};
INSTANTIATE_TEST_SUITE_P(
instance, suite, cases, name
);
// But this does not compile
INSTANTIATE_TEST_SUITE_P(
instance, suite, cases,
[](const testing::TestParamInfo<param>& info) {
const auto [a, b] = info.param;
return std::string(a) + "_to_" + std::to_string(b);
}
);
I know that in some cases like template arguments, the comma can be protected from preprocessor by an extra set of parentheses. Can the same be done here? I tried placing parentheses around the structured binding, but it did not compile either.
Answered in comments: putting entire lambda in parentheses solves the issue.
INSTANTIATE_TEST_SUITE_P(
instance, suite, cases,
([](const testing::TestParamInfo<param>& info) {
const auto [a, b] = info.param;
return std::string(a) + "_to_" + std::to_string(b);
})
);