我有一个vector<T> input
我想通过 std::sample
获得 n 个随机选择的元素来自 STL C++17 的算法 ( http://en.cppreference.com/w/cpp/algorithm/sample )。该代码在 results
情况下工作正常类型为vector<T>
。
代码示例 1(不返回指针)
auto getSamples(unsigned int noSamples, const vector<T> &input)
{
vector<T> results;
std::mt19937 twisterEngine;
std::sample(input.begin(), input.end(), std::back_inserter(results),
noSamples, twisterEngine);
return results;
}
但是,我并不是在寻找存储在 input
中的元素的值/拷贝。但我想获取指向 n 个采样元素的指针。有没有任何提示如何让 vector<T*> results
返回指针仅使用标准 C++ 代码(例如不使用 boost 库等)?我需要如何调整以下代码才能完成它?
代码示例 2(意图返回指针)
auto getSamples(unsigned int noSamples, const vector<T> &input)
{
vector<T*> results;
std::mt19937 twisterEngine;
std::sample(input.begin(), input.end(), std::back_inserter(results),
noSamples, twisterEngine);
return results;
}
最佳答案
您只需要一个OutputIterator
。它实际上并不需要像迭代器那样发出某些东西。它可以……完全做别的事情。就像调用一个函数一样。
#include <iterator>
template <class F>
struct function_output_iterator {
F f;
using iterator_category = std::output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;
function_output_iterator& operator++() { return *this; }
function_output_iterator& operator*() { return *this; }
function_output_iterator& operator++(int) { return *this; }
template <class U,
std::enable_if_t<!std::is_base_of<
function_output_iterator, std::decay_t<U>>{}, int> = 0>
void operator=(U&& u) {
f(std::forward<U>(u));
}
};
template <class F>
function_output_iterator(F ) -> function_output_iterator<F>;
然后,您可以执行任何您想要的任意操作:
auto getSamples(unsigned int noSamples, const vector<T> &input)
{
vector<T*> results;
results.reserve(noSamples);
std::mt19937 twisterEngine;
std::sample(input.begin(), input.end(),
function_output_iterator{[&](T const& elem){ results.push_back(&elem); }, // <==
noSamples, twisterEngine);
return results;
}
关于c++ - 如何在 <T> 容器上使用 std::sample 返回指针 <T*> 的容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46776846/