如何解决从迭代器中选择的函数类型成员变量 目标问题和解决方案草图问题尝试和想法
目标
问题和解决方案草图
以下是设想的解决方案的草图,其中 ???
表示选择函数的类型,我无法计算。
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
的示例用法草图。仅支持其中一部分的解决方案仍然可以。
-
结合现有功能:
auto p = Producer<int>(std::max_element)`;
-
与 lambda 函数结合使用:
auto p = Producer<int>([](auto begin,auto end)) { ... });
-
template<typename E,typename It> E my_selector(It begin,It end) { ... } auto p = Producer<int>(my_selector);
问题
如何让代码工作,即成员变量 choose_from
的正确类型是什么?
尝试和想法
我尝试使用
std::function
来输入choose_from
,但由于没有抽象迭代器类型 (AFAIK),我基本上被困在std::function<E(IT?,IT?)>
。-
如果
std::vector
中Producer::next()
的使用被泄露,我可以修复choose_from
的类型来处理std::vector<E>::iterator
,但我更愿意隐藏内部细节。
解决方法
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 个额外的间接访问)。只有在运行时多态不可避免时才应该使用它(例如动态回调)——这里不是这种情况。不要使用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。