我正在尝试使用以下构造来检查是否存在基于我之前获得的this answer的成员函数:
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进行编译:
错误C2228:'。a'的左边必须有class / struct / union类型 'add_rvalue_reference&LT; _Ty&GT; ::类型'
似乎(?)这样的编译器错误,因为declval
特别应该在未评估的decltype
表达式(see here)内工作。有没有已知的解决方法?
答案 0 :(得分:1)
MSVC 2013的尾随返回类型解析器似乎比表达式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 {};
此语法的另一个好处是返回类型检查可以使用任何type_traits
,因此您不必检查单一类型的返回值(例如,double)。