C++ 在尾部返回类型中强制转换会导致SFINAE失败

C++ 在尾部返回类型中强制转换会导致SFINAE失败,c++,c++11,templates,gcc,c++14,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), ""); s

我已经重新实现了
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>{};
}
名称空间详细信息{
模板
结构是有效的{
模板
constexpr bool操作符()(T&&)const noexcept{return true;}
constexpr bool运算符()(…)const noexcept{return false;}
};
}//名称空间详细信息
模板
constexpr auto是有效的(F&&)
{
返回详细信息::是否有效\u impl{};
}
然而,我不知道为什么Hana的用户指南建议将通缉成员的类型强制转换为无效(参见);我们不能用
decltype(t.name)
而不是
decltype((void)t.name)


此外,转换为
void
会导致测试在GCC<5.3中进行,而没有转换则会导致GCC 5.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>{};
}
@来自对象的代码段示例/教程/内省.cpp非静态成员

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


使用
static_cast
而不是C-cast似乎可以解决问题:。如果您阅读了手册,它会说:注意我们如何将
x.member
的结果强制转换为
void
?这是为了确保我们的检测也适用于无法从函数返回的类型,比如数组类型。我倾向于说编译器bug,因为如果我使用
static\u cast
而不是C样式的cast,这一切都很好:
auto has\u name=is\u valid([](auto&&t)->decltype(static\u cast(t.name)){}GCC 7工程编号problem@101010不知道我怎么会错过这个:)