2017-03-13 40 views
0

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

每个矢量具有相同的大小,以便...

LIB文件:

#include <vector> 

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

    std::vector <type> vectorName; 
}; 

主文件:

#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; 
} 

#1的作品,而不是一个数组, #2没有,编译器说:“从int到非标量类型的转换'NameClass'请求” #3的作品,但是...它只是荒谬的初始化每个对象。而且我不能只在类中放入一个静态的大小,因为这个值会改变。

所以...我的研究说,我需要使用std :: generate。问题是......什么是最好的方法?

对不起,如果很容易的问题如何使用std :: generate我是初学者,并找麻烦找到最佳的解决方案。

一些人认为复杂的解决方案,但是,我一直用我的解决方案

#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; 
} 

我使用变薄,因为实在是容易理解,并工作。但我打开其他容易理解和功能解决方案。

link std::generate

+0

'NameClass object [number_objects] = {NameClass(s​​ize)}'should work我认为 – Telokis

+2

@Ninetainedo不,这[只会初始化第一个](http://coliru.stacked-crooked.com/a/ 93420d6f114844d9)(其余部分默认初始化) – Borgleader

+0

@Borgleader:从技术上讲,其余的都是初始化的。对于'vector',结果是一样的。 –

回答

1

如果使用的载体是没有问题的,其实这作品,而且非常简单。 这是一首诗......

类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

#include <vector> 
#include <algorithm> 

#include <vector> 

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

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

如果你想使用数组那么就使用默认的构造函数。

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; 
}; 

类TEST.CPP

#include <stdio.h> 

#include "class.hpp" 

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

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

    return 0; 
} 

此打印正确的输出。

0

您必须初始化向量每次,它只是你如何在代码中出示。你可以做这样的事情

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

std :: generate将为vector的每个元素初始化一个NameClass的实例。

+0

'g ++ class-main.cpp'有问题。从class-main.cpp包含的文件中:4:0: class.hpp:7:12:note:candidate:NameClass :: NameClass(unsigned int) 显式名称类(无符号大小) ^ ~~~~~~ ~~ class.hpp:7:12:注意:候选人期望1个参数,0提供 类。hpp:4:7:备注:候选人:NameClass :: NameClass(const NameClass&) class NameClass ^ ~~~~~~~~ –

+1

如果使用'std :: vector',只需执行'std :: vector 类(number_of_objects,NameClass(s​​ize));'。 – Jarod42

1

如果您愿意使用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)... }}; 
    }); 
} 

我们通过make_array<count>拉姆达。该lambda采用可转换的参数 - 从编译时间std::size_t的值为I,并返回数组的第i个元素。

结果是大小为countstd::array

lambda可能需要auto I才能获得编译时多汁性,或者只需要std::size_t I即可获取运行时版本的值。

以上大部分内容都可以转换为C++ 11,但它会变得很难看。我不喜欢丑陋的代码。

Live example

你的代码是这样:

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); }); 
} 

objects现在是一个(std::)数组的长度number_objectsNameClass,所有大小size的。

+0

虽然很有趣,但是...在我走路的方式中,使用for循环和asigne的每个尺寸都更容易,使用少量代码并且易于理解。 'object [i] .vectorName.resize(size);'从i = 0到我

1

为你的类创建一个默认的构造函数:

#include <vector> 

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

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

在主:

#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; 
} 

原因例如2不工作是因为C++没有一个语法创建数组没有提供默认构造函数的对象。

在蟒蛇它看起来像什么:

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

我离题了。

要做到没有默认的构造函数,仍然创造的,你可以使用这个列表(问题是,你为什么会想这样做):

#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; 
} 
+0

但是实现是...怎么样?你把相同的主,所以我不明白什么是与默认构造函数的区别。 –

+0

@MoisesRojo,默认的构造函数是允许你声明一个这样的项目的数组。如果没有它,编译器没有定义“NameClass”数组的所有必要信息。我进一步发布了一些东西,以展示如何在没有默认构造函数的情况下以及没有任何stl容器的情况下实现,但只能使用一些奇特的类C构造 – smac89