以尾随返回类型进行转换会导致SFINAE失败

时间:2017-01-24 13:11:26

标签: c++ c++11 templates gcc c++14

我已将boost::hana::is_valid重新用于学习目的。用例是:

struct Person {
    std::string name;
};

int main()
{
    auto has_name = is_valid([](auto&& t) -> decltype((void) t.name) {});

    Person jon{"snow"};
    static_assert(has_name(jon), "");
    static_assert(!has_name(1), "");
}

实现:

namespace detail {

template<typename F>
struct is_valid_impl {
    template<typename T, typename = std::result_of_t<F&&(T&&)>>
    constexpr bool operator()(T&&) const noexcept { return true; }

    constexpr bool operator()(...) const noexcept { return false; }
};

}  // namespace detail

template<typename F>
constexpr auto is_valid(F&&)
{
    return detail::is_valid_impl<F>{};
}

但是,我不知道为什么Hana的用户指南建议将所需成员的类型转换为void(参见here);我们不能只使用decltype(t.name)代替decltype((void) t.name)吗?

此外,对void的强制转换导致GCC中的fail测试<{3}}。 5.3,而没有为GCC 5.1+投射代码works。可能是什么原因?

1 个答案:

答案 0 :(得分:2)

不能比文档更明确:

  

@snippet example / tutorial / introspection.cpp non_static_member_from_object

     

请注意我们如何将x.member的结果转换为void这是为了确保   我们的检测也适用于无法从函数返回的类型,   像数组类型一样。

Link to the docs line