C++ 更优雅的方式在多维数组中设置默认值

Posted

技术标签:

【中文标题】C++ 更优雅的方式在多维数组中设置默认值【英文标题】:C++ More Elegant Way to set Default Values in multi-dimensional array 【发布时间】:2015-07-27 18:01:39 【问题描述】:

在我的 .h 文件中,我有:

struct tup
    tup() : 
    token-1,"a","b","c","d","e","f",
          -1,"a","b","c","d","e","f",
          ...
          -1,"a","b","c","d","e","f" 
    struct 
        int pos;
        std::string nj, ny, pa, ri, ct, fl;
     token[100];

“...”指的是 97 多行相同类型的代码。有没有更优雅的方式来为我的令牌设置默认值?

【问题讨论】:

为该内部结构创建一个默认构造函数?另外标题中提到的这个“多维”数组在哪里? @NunsBeachSurfer 为什么只有 97 个初始化器而不是 100 个?:) @VladfromMoscow 97 more lines 他们已经展示了 3。 @NathanOliver 什么时候简单地复制和粘贴这些行有什么问题? @VladfromMoscow 我实际上认为他们做到了并且想知道更好的方法。我不能责怪他们没有发布 100 行相同的代码。 【参考方案1】:

如果您愿意使用 std::vector 而不是数组,您可以使用:

struct tup
    tup() : tokens(100, -1,"a","b","c","d","e","f") 
    struct token 
        int pos;
        std::string nj, ny, pa, ri, ct, fl;
    ;
    std::vector<token> tokens;
;

【讨论】:

@NunsBeachSurfer,不客气。我很高兴能够提供帮助。【参考方案2】:

您应该在 cpp 文件中使用构造函数(以及类而不是结构)。数组的实际内容是不应该在标题中的实现细节。 最好的方法是在初始化类的方法中使用循环(100 项对于计算机来说是一个很小的数字,您不会看到差异)。它还允许您更好地处理错误(构造函数不能轻易返回错误代码;您可以为此使用引用或成员,但这很丑)。这是我能想到的最好方法。

在您的解析器中,所有字符串都只是字符吗?如果 n 是您的字符串的最大大小,您可以简单地使用 char 或 char[n+1] 。使用 std::strings,您可以对小尺寸进行静态分配(浪费一点空间),对较大尺寸进行动态分配。如果您必须处理分配错误,那么您需要一个用于初始化类的成员。因此,标头只会提供其他文件所需的最少信息(结构和大小,而不是数据)。

如果您希望以后能够阅读您的代码,我还建议您使用有意义的变量名称(它们的大小不是问题)。

100 的限制对我来说似乎是代码的味道。为什么不使用动态分配和不受限制的大小?您可以在构建集合时简单地将新的令牌值推送到集合中。默认值应该只在令牌的构造函数中,而不是在具有虚拟大小的数组中。如果稍后您扩展解析器以处理更多令牌怎么办?如果您希望代码不断发展,那么硬编码数组的最大值是一种不好的做法。当您达到极限时,您通常会在发现问题之前遇到错误。

【讨论】:

【参考方案3】:

这是一个演示程序,展示了如何定义构造函数,前提是您的编译器支持 C++ 2014。否则,您必须将类型 std::remove_extent_t 更改为 C++ 2011 中的等价类型。

#include <iostream>
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <string>

struct tup
    tup() 
     
        std::fill( std::begin( token ), std::end( token ),  
                   std::remove_extent_t<decltype( token )>( -1,"a","b","c","d","e","f" ) );
    

    struct 
        int pos;
        std::string nj, ny, pa, ri, ct, fl;
     token[100];
;

int main()

    tup tup;

    std::cout << tup.token[0].pos << ' ' << tup.token[0].nj << std::endl;
    std::cout << "//..." << std::endl;
    std::cout << tup.token[99].pos << ' ' << tup.token[99].nj << std::endl;

    

程序输出是

-1 a
//...
-1 a

也就是说,在任何情况下,您都可以使用标准算法 std::fill,如我所展示的,或者其他方式,例如使用 lambda 表达式。

【讨论】:

以上是关于C++ 更优雅的方式在多维数组中设置默认值的主要内容,如果未能解决你的问题,请参考以下文章

C++ 数组与字符串⁽²²⁾|多维数组

多维数组

在 C++ 中返回多维数组的函数

如何从多维数组开始使用 DOM 创建表?

如何用不同的默认值初始化多维数组

如何在python中将大于零的多维数组的所有值更改为1? [复制]