从迭代器中选择的函数类型成员变量

Function-typed member variable selecting from iterators

目标

问题和解决方案草图

下面是设想的解决方案的草图,??? 表示选择函数的类型,我无法计算出来。

template<typename E>
class Producer {
  ??? choose_from; // A function It × It → E
  ...
public:
  Producer(??? cf): choose_from{cf} {}

  E next() {
    // Get a bunch of values from internal state (omitted for brevity).
    // Could also be another container, e.g. std::set.
    std::vector<E> values = ...;

    return choose_from(values.begin(), values.end());
  }
}

接下来,一些这样的示例用法草图 Producer。仅支持其中一部分的解决方案仍然可以。

问题

如何让代码工作,即成员变量 choose_from 的 the/a 正确类型是什么?

尝试与思考

std::min_element 是一个函数模板,你可以单独使用它做的事情不多。函数模板有问题 - 它们不能作为模板参数传递,nor 作为函数参数传递。

如果您可以将其包装在通用 lambda 中,那么可能有一个通用解决方案:

template<class E, class F>
class Producer {
    F choose_from; // A function It - It → It

public:
    Producer(F const& cf) : choose_from{ cf } {}

    E next() {
        std::vector<E> values{ 5, 2, 3 };

        return *choose_from(values.begin(), values.end());
    }
};

template<typename E, typename F>
auto make_producer(F const& cf) {
    return Producer<E, F>(cf);
}

template<typename It>
It my_selector(It begin, It end) { return begin; }

int main() {
    auto p1 = make_producer<int>([](auto from, auto to) { return from; });
    cout << p1.next() << endl;
    auto p2 = make_producer<int>([](auto from, auto to) { return std::min_element(from, to); });
    cout << p2.next() << endl;
    auto p3 = make_producer<int>([](auto from, auto to) { return my_selector(from, to); });
    cout << p3.next() << endl;
}

备注:

  • 也没有部分 CTAD,因此即使在 C++17 中,您也需要辅助函数(上面的 make_producer())。

  • std::function 带有 运行 时间开销(1..2 额外的间接寻址)。它应该只在 运行 时间多态性不可避免时使用(例如动态回调)——这里不是这种情况。请勿使用。