部分模板类型扣除

时间:2016-04-06 18:36:50

标签: c++ templates c++11

我正在编写一个模板,用于在编译时指定的索引中按元素对元组进行排序。我的代码有效,但使用起来很痛苦,因为我必须指定用于对元组元素进行排序的二进制函数的类型。

template <typename BinaryFunction, int Index>
struct sort_by_index_t {
  explicit sort_by_index_t(const BinaryFunction& binary_function)
      : binary_function(binary_function) {}

  template <typename Tuple>
  bool operator()(const Tuple& left, const Tuple& right) const {
    return binary_function(std::get<Index>(left),
                           std::get<Index>(right));
  }

 private:
  const BinaryFunction binary_function;
};

template <typename BinaryFunction, int Index>
sort_by_index_t<BinaryFunction, Index>
sort_by_index(const BinaryFunction& binary_function) {
  return sort_by_index_t<BinaryFunction, Index>(binary_function);
}

因此,如果我想按元组中的第一个元素排序,我必须输入:

sort_by_index<std::less<char>, 0>(std::less<char>());

相反,我宁愿使用如下所示的界面来避免重复,但目前还没有编译。

sort_by_index<0>(std::less<char>());

我没有看到自动推断Index的方式(并且没有必要),但sort_by_index应该能够推断出BinaryFunction的类型。

如何重写上述内容,以便我不需要指定BinaryFunction的类型?

2 个答案:

答案 0 :(得分:4)

Index不可扣除,因此必须明确提供。明确提供的模板参数只能从左到右提供,而模板参数的排序并不重要,因此只需对它们进行重新排序以确保Index是一个简单的修复方法。先走了:

template <int Index, typename BinaryFunction> // only this line needs to change
sort_by_index_t<BinaryFunction, Index>
sort_by_index(const BinaryFunction& binary_function) {
  return sort_by_index_t<BinaryFunction, Index>(binary_function);
}

尽管如此,这并不令人满意,因为我们将两个看似无关的东西 - 我们用作比较器的二进制函数以及我们实际比较的数据混为一谈。我们必须在这里编写很多代码,这些代码基本上只是重复的样板。

ranges proposal,Eric Niebler,Sean Parent和Andrew Sutton争论算法采取可调整的预测。如果你有一个C ++ 14编译器,我鼓励你实现它们,这样你就可以写下这样的东西:

// polymorphic getter
template <size_t I>
auto getter() {
    return [](auto&& tuple) {
        return std::get<I>(std::forward<decltype(tuple)>(tuple));
    };
}

// just use the getter as a projection
std::sort(container_of_tuples,
    std::less<char>{},  // this is the binary function
    getter<0>());       // this is the projection

答案 1 :(得分:0)

模板类型推导从右到左工作。如果必须指定最右边的模板参数,那么每个其他模板参数也必须如此。以下对上述的略微修改允许更清晰的界面。从本质上讲,Index模板参数必须在BinaryFunction之前,因为sort_by_index无法自动推导Index

template <int Index, typename BinaryFunction>
struct sort_by_index_t {
  explicit sort_by_index_t(const BinaryFunction& binary_function)
      : binary_function(binary_function) {}

  template <typename Tuple>
  bool operator()(const Tuple& left, const Tuple& right) const {
    return binary_function(std::get<Index>(left),
                           std::get<Index>(right));
  }

 private:
  const BinaryFunction binary_function;
};

template <int Index, typename BinaryFunction>
sort_by_index_t<Index, BinaryFunction>
sort_by_index(const BinaryFunction& binary_function) {
  return sort_by_index_t<Index, BinaryFunction>(binary_function);
}

以下编译:

sort_by_index<0>(std::less<char>());
相关问题