Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic lambda argument for std::pair

Tags:

c++

c++14

I'm trying to see if this is possible in the C++14 generic lambda, but I cannot find a right way to express it (or perhaps it is not possible). The simplified example is:

auto confirmOperation = [](auto pr){
  assert(pr.second);
};

The idea is that if you pass it an std::pair where the second is a bool (such as what is returned from emplace functions), it can look at this bool.

If this was a template parameter instead, I could explicitly show the pair with the types of the pair as generic, but I don't think that is possible with a lambda? Thus instead I mark the entire argument as generic, and thus the compiler doesn't seem able to deduce that I'm passing it the return of a map's emplace().

Any way to do this?

like image 352
johnbakers Avatar asked Jun 10 '16 13:06

johnbakers


Video Answer


3 Answers

You can constrain a lambda using enable_if:

auto confirmOperation = [](auto pr) ->
    std::enable_if_t<std::is_same<decltype(pr.second), bool>::value> {
  assert(pr.second);
};

Example.

like image 117
ecatmur Avatar answered Oct 24 '22 18:10

ecatmur


You could define an implementation details template function:

template<typename T>
void lambda_impl(std::pair<T, bool> const &p) {
  assert(p.second);
}

and then call this in your lambda as:

auto f = [](auto p) { lambda_impl(p); };

The following scheme may be available in the future with the advent of Concepts-Lite. For the time being it works only on GCC:

auto f = [](std::pair<auto, auto> const &p) { assert(p.second); };

or even better:

auto f = [](std::pair<auto, bool> const &p) { assert(p.second); };

P.S Clang is correct not to compile this due to the fact that auto parameters are not part of C++14.

like image 1
101010 Avatar answered Oct 24 '22 16:10

101010


Seems like you could just use is_same and static_assert here:

[](auto pr){
    static_assert(is_same_v<decltype(pr.second), bool>);
    assert(pr.second);
};

Or if C++17 is not an option, a message to static_assert is required and you won't be able to use is_same_v:

[](auto pr){
    static_assert(is_same<decltype(pr.second), bool>::value, "ouch");
    assert(pr.second);
}

Live Example

like image 1
Jonathan Mee Avatar answered Oct 24 '22 17:10

Jonathan Mee