1

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.

2
  • 5
    Have you tried putting the whole lambda in a set of parentheses? Like ([](const testing::TestParamInfo<param>& info) { ... })? Commented Feb 14 at 9:35
  • if you dont remove includes from the code then anybody passing by can copy the code to compile it and see the error within a blink. If you remove them one would have to redo work you already did, thats not nice Commented Feb 14 at 9:55

1 Answer 1

3

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);
    })
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.