标签: if constexpr

  • C++17 新特性—— if constexpr

    看代码说话

    template <typename Iterator>
    auto distance(Iterator begin, Iterator end) {
      using Traits = std::iterator_traits<Iterator>;
      if constexpr (std::is_base_of_v<std::random_access_iterator_tag, typename Traits::iterator_category>) {
        return end - begin;
      } else {
        auto result = typename Traits::difference_type();
        for (auto it = begin; it != end; ++it) {
          ++result;
        }
        return result;
      }
    }

    上面的代码用来判断两个iterator之间的距离。主要逻辑是判断iterator是否是可随机访问的iterator然后作分支处理,可以随机访问的迭代器直接把iterator相减。
    constexpr if语句中,条件的值必须是可按语境转换到 bool 类型的经转换常量表达式。若其值为 true,则舍弃 false分支语句(若存在),否则舍弃 true分支语句。有意思的一点是,被舍弃语句中的 return 语句不参与函数返回类型推导,也就是说两个分支语句中的return推倒出来的类型允许不一样。

    如果没有C++17这种怎么写呢?就是比较麻烦。
    一可以加一个参数,但是每个tag写一个

    template <typename Iterator>
    auto distance(Iterator begin, Iterator end, std::bidirectional_iterator_tag); // one for each tag type

    或者用SFINAE写两个

    template <typename Iterator>
    auto distance(Iterator begin, Iterator end, 
                  typename std::enable_if_t<std::is_base_of_v<一大坨>>* = nullptr);