用回调初始化向量

Initialize a vector with a callback

本文关键字:向量 初始化 回调      更新时间:2023-10-16

我有一个类:

MyType callback(){
 /// randomize here
 .....
 .....
 return randomValue;
}
class MyClass{
private:
  std::vector< MyType > m_vector;
public:
  MyClass( unsigned int size ):m_vector(size, callbackHere? );
};

我需要用我生成的值初始化向量,我该怎么做?一种解决方案是为mytype制作一个空的构造函数,这就是我所拥有的,但是现在我想通过一对替换mytype,因此空构造函数不起作用。

我的回调将返回随机值,因此我想拥有一个内部有一些随机值的向量。

谢谢

您可以编写类似自定义迭代的类型

  • 调用pre-pre-postfix ++时会生成一个新值
  • 通过operator*
  • 对生成的值产生生成的值
  • 完成生成值后,等于某些哨兵对象(end迭代器)

您可以让"回调"返回完全生成的向量:

std::vector<std::pair<A, B>> callback(unsigned int size){
  std::vector<std::pair<A, B>> v;
  // Build vector
  return v;
}

然后,您可以使用其移动构造函数来初始化m_vector

MyClass(unsigned int size) : m_vector(callback(size)) { }

您可以使用std::generate_n

std::vector<MyType> v (n);
std::generate_n (v.begin (), n, callback);

变体:

std::vector<MyType> v;
std::generate_n (std::back_inserter (v), n, callback);

,如果您绝对希望在构造函数初始化器中,将其放在静态功能中,如Joseph的答案。

您可以构建一个initializer_list:

#include <iostream>
#include <vector>
typedef std::initializer_list<int> (*callback_function)();
std::initializer_list<int> values() {
    return { 1, 2, 3 };
}
struct X {
    std::vector<int> v;
    X(callback_function f) : v(f()) {};
};
int main() {
    X x(values);
    for(int i: x.v) std::cout << i;
    std::cout << 'n';
}

注意:您将使约束器中的大小松开。

我对此有些乐趣。以下代码为所有C 11。

#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <random>
class my_random_generator {
        private:
        static std::random_device rd;
        std::mt19937 gen;
        std::uniform_int_distribution<int> dis;
        public:
        my_random_generator() :
                gen(rd()),
                dis(std::numeric_limits<int>::min(), std::numeric_limits<int>::max())
        {}
        int operator()() {
                return dis(gen);
        }
};
std::random_device my_random_generator::rd;
int main()
{
        std::vector<int> v;
        std::generate_n(std::back_inserter(v), 500, my_random_generator());
        for(auto const &i: v)
                std::cout << i << ',';
        std::cout << std::endl;
        return 0;
}

编写一个函数以返回向量已经填充的函数是最简单的解决方案,但是如果您想使用自定义迭代器,这里可能是基本实现

#include <iostream>
#include <vector>
#include <iterator>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    for (auto& el : vec)
      os << el << ' ';
    return os;
}
template <typename F >
struct GenerateIterator : std::iterator<std::input_iterator_tag, typename std::remove_reference<decltype(std::declval<F>()())>::type> {
    using value_type = typename std::remove_reference<decltype(std::declval<F>()())>::type;
    GenerateIterator() = default;
    GenerateIterator( F &&f, std::size_t num = 0 ) : num_(num), f_(std::forward<F>(f)) {}
    bool operator!=( GenerateIterator const & o ) { return num_ != o.num_; }
    GenerateIterator& operator++(  ) { --num_; return *this; }
    value_type operator*() { return f_(); }
private:
    std::size_t num_{};
    F f_;
};
template <typename F >
GenerateIterator<F>
MakeGenerateIterator( F &&f, std::size_t num = 0 ) {
    return { std::forward<F>(f), num };
}
int bar() {
    static int val{};
    return 2* val++;
}
int main() {
    std::vector<int> foo( MakeGenerateIterator(bar, 10), MakeGenerateIterator(bar) );
    std::cout << foo << std::endl;
}

我找到了一个解决方案:D对此感到非常高兴:

组合boost :: transform_iterator和boost :: counting_iterator是我在这里需要的

   std::pair<float, float> createInput(unsigned int){
        std::pair<float, float> input(utils::createRandom<float>(1), utils::createRandom<float>(1));
        return input;
    }
Neuron ( unsigned int inputsNumber = 1 ) :  m_neuronWeight( utils::createRandom<Var>(1) ), 
                                            m_output(0), 
                                            m_sum(0),
                                            m_inputs(boost::make_transform_iterator( boost::counting_iterator<unsigned int>(0), createInput ),
                                                     boost::make_transform_iterator( boost::counting_iterator<unsigned int>(inputsNumber), createInput )) {
    if ( inputsNumber == 0 ) {
        throw NNException ( "Wrong argument inputsNumber==0", __FILE__, __LINE__ );
    }
}

希望对您和我有用:)