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不知道我怎么会错过这个:)