msvc2013 的 decltype 模板出错
error with decltype template with msvc2013
我正在尝试使用以下构造来检查是否存在基于我之前获得的 的成员函数:
template <typename T, class = double>
struct has_a : std::false_type {};
template <typename T>
struct has_a<T, decltype(std::declval<T>().a())> : std::true_type {};
这适用于 gcc 4.9.2,但无法使用 msvc2013 进行编译:
error C2228: left of '.a' must have class/struct/union type is
'add_rvalue_reference<_Ty>::type'
似乎(?)这是一个编译器错误,因为 declval
专门应该在未计算的 decltype
表达式 (see here) 中工作。有已知的解决方法吗?
MSVC 2013 的尾部 return 类型解析器似乎比表达式 SFINAE 系统更完整,如果检查器按以下方式重构 (following T.C's suggestion),它在 msvc2013 上都按预期工作和 gcc 4.9.2:
template <typename T>
struct has_a_impl
{
template<typename U>
static auto test(U* p) -> decltype(p->a()); // checks function existence
template<typename U>
static auto test(...) -> std::false_type;
using type = typename std::is_floating_point<decltype(test<T>(0))>::type; // checks return type is some kind of floating point
};
template <typename T>
struct has_a : has_a_impl<T>::type {};
此语法的另一个好处是 return 类型检查可以使用任何 type_traits
,因此您不必检查单一类型的 return 值(例如双)。
我正在尝试使用以下构造来检查是否存在基于我之前获得的
template <typename T, class = double>
struct has_a : std::false_type {};
template <typename T>
struct has_a<T, decltype(std::declval<T>().a())> : std::true_type {};
这适用于 gcc 4.9.2,但无法使用 msvc2013 进行编译:
error C2228: left of '.a' must have class/struct/union type is 'add_rvalue_reference<_Ty>::type'
似乎(?)这是一个编译器错误,因为 declval
专门应该在未计算的 decltype
表达式 (see here) 中工作。有已知的解决方法吗?
MSVC 2013 的尾部 return 类型解析器似乎比表达式 SFINAE 系统更完整,如果检查器按以下方式重构 (following T.C's suggestion),它在 msvc2013 上都按预期工作和 gcc 4.9.2:
template <typename T>
struct has_a_impl
{
template<typename U>
static auto test(U* p) -> decltype(p->a()); // checks function existence
template<typename U>
static auto test(...) -> std::false_type;
using type = typename std::is_floating_point<decltype(test<T>(0))>::type; // checks return type is some kind of floating point
};
template <typename T>
struct has_a : has_a_impl<T>::type {};
此语法的另一个好处是 return 类型检查可以使用任何 type_traits
,因此您不必检查单一类型的 return 值(例如双)。