简体   繁体   English

初始化对象数组中的向量大小

[英]Initialize vectors size in array of objects

I want to initialize the sizes of vectors in an array of objects. 我想初始化对象数组中向量的大小。

Every vector have the same size so... 每个向量都有相同的大小,所以...

LIB FILE: 库文件:

#include <vector>

Class NameClass
{
 public:
  explicit NameClass( unsigned size )
  {
    vectorName.resize( size );
  }

  std::vector <type> vectorName;
};

MAIN FILE: 主文件:

#include "lib.hpp"

int main( void )
{
  NameClass object( size ); #1

  NameClass object[ number_objects ]( size ); #2
  NameClass object[ number_objects ] = {NameClass(size), NameClass(size), ... }; #3

  return 0;
}

The #1 works, but is not an array, The #2 doesn't, compiler says "conversion from int to non-scalar type 'NameClass' requested" And #3 works, but... it's just absurd initialize every object. #1有效,但不是数组,#2无效,编译器说“请求从int转换为非标量类型'NameClass'”,而#3有效,但是...荒谬地初始化每个对象。 and I can't just put a static to size inside the class, because the value change. 而且我不能只在类中放入static大小,因为值会改变。

So... My research say that I need use std::generate. 所以...我的研究表明我需要使用std :: generate。 the question is... Whats is the best way? 问题是...什么是最好的方法?

Sorry if is easy question how to use std::generate I'm beginner and get troubles to find the optimal solution. 对不起,如果很容易问问题,如何使用std :: generate我是新手,很难找到最佳解决方案。

Some people suggest complex solutions but, I keep using my solution 有人建议复杂的解决方案,但我一直在使用我的解决方案

#include "lib.hpp"

int main( void )
{
  unsigned number_objects = something;
  unsigned size = other_thing;
  NameClass object[ number_objects ];

  for( unsigned i = 0; i < number_objects; i++)
    object[i].vectorName.resize( size );

  return 0;
}

I use thins because is really easy to understand , and works . 我使用Thins是因为它很容易理解并且可以正常工作 But I'm open to other easy to understand and functional solutions. 但是我愿意接受其他易于理解和实用的解决方案。

link std::generate 链接std :: generate

If you are willing to use std::array and C++14, we get: 如果您愿意使用std::array和C ++ 14,我们将获得:

template<std::size_t...Is>
auto index_over( std::index_sequence<Is...> ) {
  return [](auto&&f)->decltype(auto) {
    return decltype(f)(f)(std::integral_constant<std::size_t, Is>{}...);
  };
}
template<std::size_t N>
auto index_upto( std::integral_constant<std::size_t, N> ={} ) {
  return index_over( std::make_index_sequence<N>{} );
}

template<std::size_t N, class F,
  class T = std::decay_t<std::result_of_t< F&( std::integral_constant<std::size_t, 0>& )>>,
  class R = std::array<T, N>
>
R make_array( F&& f ) {
  return index_upto<N>()( [&](auto...Is)->R {
    return {{ f( Is )... }};
  } );
}

we pass make_array<count> a lambda. 我们通过make_array<count>一个lambda。 That lambda takes an argument convertible-from a compile-time std::size_t whose value is I, and returns the Ith element of the array. 该lambda接受一个可转换值(来自编译时std::size_t其值为I),并返回数组的第I个元素。

The result is a std::array of size count . 其结果是一个std::array大小的count

The lambda could take an auto I to get the compile-time juiciness, or just std::size_t I to get a runtime version of the value. Lambda可以使用auto I来获取编译时的多汁性,或者可以使用std::size_t I来获取值的运行时版本。

Most of the above can be translated into C++11, it just gets ugly. 上面的大多数内容都可以翻译成C ++ 11,这很难看。 And I don't like ugly code. 而且我不喜欢难看的代码。

Live example . 现场例子

Your code would look like: 您的代码如下所示:

int main( void )
{
  unsigned size = 17;
  constexpr std::size_t number_objects = 3;

  auto objects = make_array<number_objects>( [&](std::size_t){ return NameClass(size); } );
}

and objects is now a ( std:: ) array of NameClass of length number_objects , all of size size . objects现在是NameClass的( std:: NameClass数组,长度为number_objects ,大小均为size

Create a default constructor for your class: 为您的类创建一个默认的构造函数:

#include <vector>

class NameClass {
 public:
 NameClass() {} // default constructor

 explicit NameClass( unsigned size ){
    vectorName.resize( size );
 }
 std::vector <type> vectorName;
};

In main: 在主要方面:

#include "lib.hpp"

int main( void )
{
  unsigned number_objects = something;
  unsigned size = other_thing;
  NameClass object[ number_objects ];

  for( unsigned i = 0; i < number_objects; i++)
    object[i].vectorName.resize( size );

  return 0;
}

The reason example 2 wasn't working is because C++ does not have a syntax for creating an array of objects for which a default constructor is not provided. 示例2不起作用的原因是因为C ++没有用于创建未提供默认构造函数的对象数组的语法。

In python it would look something like: 在python中,它看起来像:

[NameClass(size) for _ in range(number_objects)]

I digress. 我离题了。

To do without the default constructor and still create a list of, you can use this (question is why you would want to do this): 要在没有默认构造函数的情况下仍然创建列表,可以使用此命令(问题是为什么要这样做):

#include <iostream>

static constexpr unsigned NUM_OBJECTS = 10;
static constexpr unsigned VEC_SIZE = 30;

int main() {
    NameClass *objects = static_cast<NameClass *>(operator new [](NUM_OBJECTS * sizeof *objects));

    for (unsigned i = 0; i < NUM_OBJECTS; i++) {
        objects[i].vectorName.resize(VEC_SIZE);
    }

    // Required to free memory
    operator delete[](objects);

    return 0;
}

If use vectors is not a problem, actually this works, and is really easy. 如果使用向量不是问题,那么实际上这是可行的,而且确实很容易。 It's a poem... 这是一首诗...

class-test.cpp class-test.cpp

#include <stdio.h>
#include <algorithm>

#include "class.hpp"

int main( void )
{
  std::vector <NameClass> object(number_objects, NameClass(size));

  printf("%lu\n", object[0].vectorName.size() );

  return 0;
}

class.hpp class.hpp

#include <vector>
#include <algorithm>

#include <vector>

class NameClass {
 public:
 NameClass() {} // default constructor

 explicit NameClass( unsigned size ){
    vectorName.resize( size );
 }
 std::vector <double> vectorName;
};

And if you want use arrays then just use the default constructor. 如果要使用数组,则只需使用默认构造函数即可。

clas.hpp clas.hpp

#include <vector>

class NameClass {
 public:
 NameClass(unsigned size) {
 vectorName.resize( size ); 
 } // default constructor

 explicit NameClass( unsigned size ){ // eliminate this
    vectorName.resize( size );
 }
 std::vector <type> vectorName;
};

class-test.cpp class-test.cpp

#include <stdio.h>

#include "class.hpp"

int main() {
  NameClass objects[2](4);

  printf("%lu\n", objects[0].vectorName.size());

  return 0;
}

this print a correct output. 这将打印正确的输出。

You have to initialize every vector, it just how you present it in the code. 您必须初始化每个向量,只需对其在代码中的显示方式进行初始化。 you can do something this 你可以这样做

std::vector<NameClass> classes(number_of_objects);
std::generate(classes.begin(), classes.end(), []{return NameClass(size);});

std::generate will initialize a instance of NameClass for each element of the vector. std :: generate将为向量的每个元素初始化NameClass的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM