通过类构造函数初始化成员变量 STL 向量 [英] Initializing a member variable STL vector through a class constructor

查看:29
本文介绍了通过类构造函数初始化成员变量 STL 向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下似乎有效的代码:

class MapCell{民众:整数 x, y, z;};void Test3DVector(int size_x, int size_y, int size_z){向量<向量<矢量<MapCell>>>m(size_x, vector>(size_y, vector(size_z)));for (int x = 0; x 

我想写一个类,将 3D 向量作为成员变量,在构造函数中设置维度,如下所示:

class MyClass{民众:向量<向量<向量<MapCell>>米;//不知道怎么写MyClass::MyClass(int size_x, int size_y, int size_z){//进行与 Test3DVector 相同的初始化.}};

这样我就可以做这样的事情:

void SomeFunction(){MyClass 网格(5, 5, 5);cout<<网格->m[1][3][2].x<<网格->m[1][3][2].y<<网格->m[1][3][2].z<<结束;//应该输出 132}

这样做的最佳方法是什么?当向量变得非常大时,我应该避免哪些常见错误以获得最佳速度?

解决方案

更新为可变参数版本

1.简单、明确的代码

class MyClass {民众:向量<向量<向量<MapCell>>米;MyClass(int size_x, int size_y, int size_z): m(size_x,矢量<矢量>(尺寸_y,矢量(size_z))){}};

2.有帮手

class MyClass {向量<向量<向量<MapCell>>米;民众:MyClass(int size_x, int size_y, int size_z): m(Dim(size_z, Dim(size_y, Dim(size_x, MapCell())))) {}私人的:模板 静态 std::vector暗淡(size_t n,T&& v){返回 std::vector(n, std::move(v));}};

3.使用可变参数帮助器

因为可变参数是可变参数! 这是一个使用可变参数来让东西变得更漂亮的版本(取决于口味):

struct MyClass{向量<向量<向量<MapCell>>米;MyClass(int size_x, int size_y, int size_z): m(vec_matrix(MapCell(), size_z, size_y, size_x)){ }私人的:模板 静态 std::vectorvec_matrix(T v, size_t n) {返回 { n, std::move(v) };}模板 <typename T, typename... Dim>静态自动 vec_matrix(T v, size_t n, Dim...其他)->std::vector{返回 { n, vec_matrix(v, 其他...) };}};

附注.我稍微编辑了代码以使其更符合标准.模板和 trailing-return-type 表示同名的重载.有关此处问题的详细分类,请参阅聊天中的此讨论书签

如果您的编译器不相信它应该工作,请查看它live on gcc 4.7.2.它仅使用 boost 来格式化输出:

<预><代码>....................-------....................


在 SO 上避免链接失效的完整代码:

#include #include <向量>#include //仅用于调试输出使用命名空间标准;struct MapCell{朋友 std::ostream&运算符 <<(std::ostream& os, MapCell const&){返回操作系统<<.";}};结构体{向量<向量<向量<MapCell>>米;MyClass(int size_x, int size_y, int size_z): m(vec_matrix(MapCell(), size_z, size_y, size_x)){ }私人的:////////////////////////////////////////////////////可变参数是 funadic!模板 静态 std::vectorvec_matrix(T v, size_t n){返回 { n, std::move(v) };}模板 <typename T, typename... Dim>静态自动 vec_matrix(T v, size_t n, Dim...其他)->std::vector{返回 { n, vec_matrix(v, 其他...) };}////////////};int main(){我的类 a(4,5,2);使用命名空间 boost::spirit::karma;std::cout<<格式(流 % ' ' % eol % "\n-------\n", a.m)<<std::endl;}

I have the following code which seems to work:

class MapCell
{
    public:
    int x, y, z;
};

void Test3DVector(int size_x, int size_y, int size_z)
{
    vector< vector< vector<MapCell> > > m(size_x, vector<vector<MapCell>>(size_y, vector<MapCell>(size_z)));

    for (int x = 0; x < size_x; ++x)
    {
        for (int y = 0; y < size_y; ++y)
        {
            for (int z = 0; z < size_z; ++z)
            {
                m[x][y][z].x = x;
                m[x][y][z].y = y;
                m[x][y][z].z = z;
            }
        }
    }
}

I want to write a class that has the 3D vector as a member variable, with the dimensions set in the constructor, like so:

class MyClass
{
    public:
        vector< vector< vector<MapCell>>> m;    // I'm not sure how to write this
    MyClass::MyClass(int size_x, int size_y, int size_z)
    {
        // Do the same initialization as Test3DVector did.

    }
 };

So that I can do something like this:

void SomeFunction()
{
   MyClass grid(5, 5, 5);
   cout << grid->m[1][3][2].x << grid->m[1][3][2].y << grid->m[1][3][2].z << endl;
   // Should output 132
}

What is the best way to do this? When the vectors become very large are there any common mistakes that I should avoid to get the best speed?

解决方案

updated with a variadic version

1. Simple, explicit code

class MyClass {
public:
    vector<vector<vector<MapCell>>> m;
    MyClass(int size_x, int size_y, int size_z)
        : m(size_x,
            vector<vector<MapCell> >(
                size_y,
                vector<MapCell>(size_z)
            )
           ) {
    }
};

2. With a helper

class MyClass {
    vector<vector<vector<MapCell>>> m;
public:
    MyClass(int size_x, int size_y, int size_z)
        : m(Dim(size_z, Dim(size_y, Dim(size_x, MapCell())))) {
    }

private:
    template <typename T>
    static std::vector<T> Dim(size_t n, T&& v) {
        return std::vector<T>(n, std::move(v));
    }
};

3. With a variadic helper

Because variadics are funadic! here is a version using variadics to make things ... prettier (depending on taste):

struct MyClass
{
    vector<vector<vector<MapCell>>> m;
    MyClass(int size_x, int size_y, int size_z)
        : m(vec_matrix(MapCell(), size_z, size_y, size_x))
    { }

private:
    template <typename T> static std::vector<T> vec_matrix(T v, size_t n) {
        return { n, std::move(v) };
    }

    template <typename T, typename... Dim> static auto vec_matrix(T v, size_t n, Dim... other)
        -> std::vector<decltype(vec_matrix(v, other...))> {
        return { n, vec_matrix(v, other...) };
    }
};

PS. I have slightly edited the code to be more standards-compliant. There is a subtle issue with templates and trailing-return-type that refers to an overload of the same name. For a nice breakdown of the issue here, see this discussion bookmark in chat

In case your compiler doesn't believe it should work, see it live on gcc 4.7.2. It uses boost only to format the output:

. . . .
. . . .
. . . .
. . . .
. . . .
-------
. . . .
. . . .
. . . .
. . . .
. . . .


Full code to avoid link-rot on SO:

#include <iostream>
#include <vector>
#include <boost/spirit/include/karma.hpp> // for debug output only

using namespace std;

struct MapCell 
{
    friend std::ostream& operator <<(std::ostream& os, MapCell const&)
    { return os << "."; }
};

struct MyClass
{
    vector<vector<vector<MapCell>>> m;
    MyClass(int size_x, int size_y, int size_z)
        : m(vec_matrix(MapCell(), size_z, size_y, size_x))
    { }

private:
   ///////////////////////////////////////////////////
   // variadics are funadic!
   template <typename T> static std::vector<T> vec_matrix(T v, size_t n) 
   {
      return { n, std::move(v) };
   }

   template <typename T, typename... Dim> static auto vec_matrix(T v, size_t n, Dim... other)
      -> std::vector<decltype(vec_matrix(v, other...))> 
   {
      return { n, vec_matrix(v, other...) };
   }
   ////////////
};

int main()
{
    MyClass a(4,5,2);

    using namespace boost::spirit::karma;
    std::cout 
        << format(stream % ' ' % eol % "\n-------\n", a.m) 
        << std::endl;
}

这篇关于通过类构造函数初始化成员变量 STL 向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆