我正在尝试使用以下构造来检查是否存在基于 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 进行编译:
error C2228: left of '.a' must have class/struct/union type is 'add_rvalue_reference<_Ty>::type'
看起来(?)这是一个编译器错误,因为 declval
专门应该在未计算的 decltype
表达式中工作 (see here) .有已知的解决方法吗?
最佳答案
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)。
关于c++ - msvc2013 的 decltype 模板出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34595072/