【问题标题】:Using `hana::is_valid` fails with const references使用 `hana::is_valid` 因 const 引用而失败
【发布时间】:2018-08-12 00:10:29
【问题描述】:

我正在使用 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&amp;,我们就会收到没有合适的重载的错误:godbolt

所以我的问题是:为什么会发生这种情况?

【问题讨论】:

  • 最好在你的问题中包含错误信息。
  • clang 的解决方法:std::enable_if_t&lt;has_length(T{}), void&gt;。但是,GCC 会抱怨任何一种方式。
  • @ildjarn 我完全忘记了.....
  • @ildjarn:如果同时添加constexpr mine()constexpr mine(const mine&amp;),那么it works
  • @ildjarn:我的评论不够清楚,抱歉:这与constexpr 无关。如果添加复制构造函数,则还应添加默认构造函数。然后clang compiles the example with auto foo(T).

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


【解决方案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{});
}

【讨论】:

    猜你喜欢
    • 2023-01-27
    • 2014-08-10
    • 1970-01-01
    • 2012-06-19
    • 2012-08-08
    • 2013-08-06
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多