简体   繁体   中英

What does boost::hana::always do more than just “always return its first argument”?

At the doc page of boost::hana::always I read that

always(x) is a function such that

always(x)(y...) == x

for any y... .

This makes me think that it shouldn't behave any differently than this lambda: [](auto const&...){ return false; } [](auto const&...){ return false; } .

However it does. For instance, the following code prints 11 , but if I change the third lambda to hana::always(false) , then it prints 00 , revealing that always is swallowing any argument.

#include <boost/hana/functional/always.hpp>
#include <boost/hana/functional/overload.hpp>
#include <iostream>

auto fun = boost::hana::overload(
        [](int){ return true; },
        [](double){ return true; },
        [](auto const&...){ return false; }
        );

int main() {
    std::cout << fun(1) << fun(1.0) << std::endl;
}
  • Is this expected?
  • If so, why?
  • Whether or not is expected, what causes this behavior?

By the way, I've just discovered boost::hana::overload_linearly , which is not an alternative to boost::hana::overload in this case (because as much as always would not get all the calls, it would be the [](int){ return true; } to be greedy), but it's good to know of it.

In fact, always has different overloads (as it handles reference as return value).

so, with a simplified version:

template <typename T>
struct my_always
{
     T res;

     template <typename ...&& Ts>
     T& operator ()(Ts&&...) /* mutable */ { return res; } // #1

     template <typename ...&& Ts>
     const T& operator ()(Ts&&...) const { return res; } // #2
};

then

auto fun = boost::hana::overload(
        my_always<bool>{ false }, // #1 & #2
        [](int){ return true; }   // #3
        );

std::cout << fun(1);

Possible overloads are:

  • bool& my_always<bool>::operator ()(int&&) #1
  • const bool& my_always<bool>::operator ()(int&&) const #2
  • bool lambda::operator() (int) const #3

All are viable here, but #1 is the best match (as fun is not const (and int is not better than int&& )).

With const fun , #3 would be the best match (#1 not viable, tie-breaker between #2 and #3 is template status).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM