0

在我读到的文档页面上boost::hana::always

always(x)是一个函数,使得

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

对于任何y....

这让我认为它的行为不应该与这个 lambda: 有任何不同[](auto const&...){ return false; }

然而确实如此。例如,下面的代码打印11,但是如果我将第三个 lambda 更改为hana::always(false),那么它会打印00,这表明它always正在吞噬任何参数。

#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;
}
  • 这是预期的吗?
  • 如果是这样,为什么?
  • 无论是否预期,是什么导致了这种行为?

顺便说一句,我刚刚发现boost::hana::overload_linearly,这不是boost::hana::overload这种情况下的替代方案(因为always不会得到所有的电话,这将[](int){ return true; }是贪婪的),但很高兴知道它。

4

1 回答 1

2

事实上,always有不同的重载(因为它将引用作为返回值处理)。

因此,使用简化版本:

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
};

然后

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

std::cout << fun(1);

可能的重载是:

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

所有在这里都是可行的,但是#1最好的匹配(因为fun不是const(并且int不比int&&)更好)。

使用const fun,#3 将是最佳匹配(#1 不可行,#2 和 #3 之间的决胜局是模板状态)。

于 2021-03-17T15:53:24.763 回答