使用`hana :: is_valid`失败,并带有const引用

时间:2018-08-12 00:10:29

标签: c++ c++14 sfinae boost-hana

我正在使用hana来确定对象是否具有Length成员,如下所示:

using boost::hana::is_valid;


static const auto has_length
    = is_valid([](const auto& obj)
            -> decltype(obj.Length(),void()) {});

这很好用...我可以整日静态声明,让我心满意足。因此,下一步是从逻辑上enable_if一个函数:

template<typename T>
auto foo(T t) -> std::enable_if_t<has_length(t), void>
{
}
struct mine
{
    int Length() const { return 0; }
};

int main()
{
    foo(mine{});
}

这很好用...。但是,当我将T更改为const T&时,我们会收到以下错误:没有合适的重载:godbolt

所以我的问题是:为什么会这样?

1 个答案:

答案 0 :(得分:1)

问题在于,使用不是constexpr的引用调用函数不是constexpr。这是hana::is_valid有用的地方,因为它返回一个类似integral_constant的值,其中包含一个静态constexpr布尔值,因此我们只需要看一下返回类型即可。参见bool_

这里是一个例子:

#include <boost/hana.hpp>
#include <type_traits>

namespace hana = boost::hana;

static auto has_length = hana::is_valid([](auto&& t)
  -> decltype(t.Length()) { });

template <typename T>
auto foo(T const& t)
  -> std::enable_if_t<decltype(has_length(t)){}, void>
                   // ^-- notice the return type 
                   // is a boolean integral constant
{ }

struct mine
{
  int Length() const { return 0; }
};

int main()
{
  foo(mine{});
}