部分模板类型推导

Wil*_*son 5 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);
}
Run Code Online (Sandbox Code Playgroud)

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

sort_by_index<std::less<char>, 0>(std::less<char>());
Run Code Online (Sandbox Code Playgroud)

相反,我宁愿有一个如下所示的界面以避免重复,但它目前无法编译。

sort_by_index<0>(std::less<char>());
Run Code Online (Sandbox Code Playgroud)

我没有看到自动推断的方法Index(并且没有必要),但sort_by_index应该能够推断BinaryFunction.

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

Bar*_*rry 6

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);
}
Run Code Online (Sandbox Code Playgroud)

也就是说,这并不令人满意,因为我们将两个看似无关的东西混为一谈——我们用作比较器的二元函数和我们实际比较的数据。我们必须在这里编写大量代码,这些代码基本上只是重复的样板。

范围提案中,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
Run Code Online (Sandbox Code Playgroud)

  • @Shafizadeh [权威 C++ 书籍指南和列表](http://stackoverflow.com/q/388242/2069064) (2认同)