c++ - msvc2013 的 decltype 模板出错

标签 c++ templates visual-studio-2013 sfinae decltype

我正在尝试使用以下构造来检查是否存在基于 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/

相关文章:

c++ - 在 C++20 中使用 `std::bit_cast` 创建闭包 (lambda) 对象是否有效?

javascript - asm.js Module.ccall/Module.cwrap 回调

python - 具有自定义持有者类型的 pybind11 多重继承无法转换为基本类型

c++ - 奇怪的 "Could not deduce template argument for ' T'"错误

c++ - 在运行时识别模板类型名

c++ - 导出模板将如何实现?

visual-studio - 在解决方案中的新项目中安装 nuget 包,其中包已用于现有项目

c++ - 哈希集、 HashMap 和哈希表?

visual-studio - 如何在 Visual Studio 2013 中使用 Sass

web-config - 当 web.config 包含 ipSecurity 权限时允许 "localhost"在 iisexpress 中运行