【问题标题】:error with decltype template with msvc2013使用 msvc2013 的 decltype 模板出错
【发布时间】:2016-01-04 16:02:32
【问题描述】:

我正在尝试使用以下构造来检查是否存在基于我之前获得的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' 的左边必须有类/结构/联合类型是 'add_rvalue_reference<_ty>::type'

似乎(?)这是一个编译器错误,因为 declval 专门应该在未评估的 decltype 表达式 (see here) 中工作。有已知的解决方法吗?

【问题讨论】:

  • 这依赖于expression SFINAE,但是MSVC2013 doesn't support it(虽然我知道他们已经为下一个版本准备了一些表达式SFINAE功能)。
  • @TartanLlama 这就是我所担心的。有没有类似的成语不会破坏visual studio?
  • @NicolasHolthaus try this
  • 你有没有把不同的“check-if-class-has-function”看成check-if-class-has-function-with-signature。有一些变体也适用于 c++03
  • 据我所知,MSVC2013 似乎对函数模板返回类型中的表达式 SFINAE 有一些支持(他们在 allocator_traitsis_assignable 中使用它)。你可以试试this吗?

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


【解决方案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,因此您不必检查单一类型的返回值(例如双精度)。

【讨论】:

    猜你喜欢
    • 2015-12-24
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多