简体   繁体   English

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

[英]C++ More Elegant Way to set Default Values in multi-dimensional array

In my .h file, I have: 在我的.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];

Where the "..." refers to 97 more lines of the same type of code. 其中“ ...”是指多于97行的相同类型的代码。 Is there a more elegant way to set default values for my token? 有没有更优雅的方式来设置令牌的默认值?

If you are open to using std::vector instead of an array, you an use: 如果您愿意使用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;
};

Here is a demonstrative program that shows how the constructor could be defined provided that your compiler supports C++ 2014. Otherwise you have to change type std::remove_extent_t to its equivalent in C++ 2011. 这是一个演示程序,显示了在编译器支持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;

}    

The program outputs is 程序输出为

-1 a
//...
-1 a

That is in any case you can use standard algorithm std::fill as I showed or some other way for example using a lambda expression. 无论如何,您都可以使用我展示的标准算法std::fill或其他方式,例如使用lambda表达式。

You should use a constructor in the cpp file (and classes instead of structs). 您应该在cpp文件中使用构造函数(并且使用类而不是struct)。 The actual content of the array is an implementation detail that shouldn't be in the header. 数组的实际内容是实现细节,不应包含在标头中。 The best way is to use a loop (100 items is a tiny number for a computer, you won't see the difference) in an method that initializes the class. 最好的方法是在初始化类的方法中使用循环(100个项目对于计算机来说是一个很小的数字,您不会看到差异)。 It also allows you to handle errors better (constructors cannot return error codes easily; you could use a reference or a member for that, but it's ugly). 它还允许您更好地处理错误(构造函数无法轻松返回错误代码;您可以为此使用引用或成员,但这很丑陋)。 This is the best approach I can think of. 这是我能想到的最佳方法。

In your parser, are all the strings just characters? 在解析器中,所有字符串都是字符吗? you could simply use a char or char[n+1] if n is the largest size for yours strings. 如果n是您字符串的最大大小,则可以简单地使用char或char [n + 1]。 With std::strings, you have static allocation for small sizes (wasting a bit of space) and dynamic allocation for larger sizes. 使用std :: strings,您可以为小尺寸分配静态分配(浪费一点空间),为大尺寸分配动态分配。 If you have to handle allocation errors, an member for initializing the class is what you need. 如果必须处理分配错误,则需要一个用于初始化类的成员。 Thus, the header will only provide the minimal information necessary for other files (structure and size, not data). 因此,标头将仅提供其他文件所需的最少信息(结构和大小,而不是数据)。

If you want to be able to read your code later, I also suggest that you use meaningful variables names (their sizes is not a problem). 如果您希望以后能够阅读代码,我还建议您使用有意义的变量名(它们的大小没有问题)。

That limit of 100 looks like code smells to me. 100的限制对我来说就像是代码的味道。 Why not use dynamic allocation and unrestricted size? 为什么不使用动态分配和不受限制的大小? you could simply push new token values in a collection when you build them. 您可以在构建新令牌值时将其推入集合中。 The default values should only be in the token's constructor, not in a array with a dummy size. 默认值应仅在令牌的构造函数中,而不能在虚拟大小的数组中。 What if later you extend your parser to handle more tokens? 如果以后再扩展解析器以处理更多令牌怎么办? hard-coded maximum values for arrays are a bad practice if you want your code to evolve. 如果您想让代码演化,则对数组进行硬编码的最大值是一个不好的做法。 When you reach the limit, you often experience bugs before you notice what's wrong. 当达到极限时,您常常会在发现错误之前先遇到错误。

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

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