如何在C++中使用for循环初始化类变量?

qqrboqgw  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(158)

我的示例类有一个静态字符数组,我想创建一个从字符到索引的Map。我需要在example.cpp文件的for循环中初始化这个静态Map。然而,C++“需要一个声明”。有什么方法可以将我的Map填充为声明吗?一般来说,在调用类变量的构造函数之前,是否有可能为静态变量创建一个构造函数来处理所有的初始化?
这是我的示例类。

#include <map>
using namespace std;
class Example {
    static char chars[4];
    static map<char,int> char2idx;
};

char Example::chars[4] = {'a','b','c','d'};
for(int i=0; i<4;i++) {
    Example::char2idx[Example::chars[i]] = i;
}

当我试图编译时,我得到了以下错误。

clang++ -std=c++11 -Wall -g -c -o example.o example.cpp
example.cpp:9:1: error: expected unqualified-id
for(int i=0; i<4;i++) {
^
1 error generated.
but5z9lq

but5z9lq1#

快速修复:创建一个辅助函数

#include <map>
using namespace std;
class Example {
    friend map<char,int> helper(); // so it can see the private members
    static char chars[4];
    static map<char,int> char2idx;
};

map<char,int> helper() // does the work, returns the map
{
    map<char,int> out;
//    for(int i=0; i<4;i++) {  that four is ugly. What if chars changes in size?
    for(int i=0; i<std::size(Example::chars);i++) { // if we didn't want i I'd use 
                                                    // a range-based for to make 
                                                    // life even simpler.  
        out[Example::chars[i]] = i;
    }
    return out; // return by value. copy elision is your friend!
}

char Example::chars[4] = {'a','b','c','d'};
map<char,int> Example::char2idx = helper();
wkftcu5l

wkftcu5l2#

C++中的ur-example是std::cinstd::cout等的初始化,核心技巧是在全局命名空间中有一个调用静态构造函数的局部静态变量:
example.hpp

class Example
{
  static stuff here;
  static bool initialize();
};

static bool b_initialize_Example = Example::initialize();

example.cpp

bool Example::initialize()
{
  static bool is_initialized = false;
  if (!is_initialized)
  {
    // do your for loop here.
  }
  return is_initialized = true;
}

另一种方法是使用工厂来生成类的示例。第一次生成示例时,初始化静态数据。

// No example here. Google around factory methods.
// You’ll still need a static bool is_initialized somewhere.

最后,你可以在类的构造函数中使用一个静态初始化器,这和第一个方法类似:

class Example
{
  Example() { initialize(); ... }

  static void initialize()
  {
    static bool is_initialized = false;
    if (is_initialized) return;
    // initialize stuff here
    is_initialized = true;
  }
};

我相信还有其他的方法来解决这个问题,但这就是我的想法。
编辑:另一个答案中的例子也很好!

相关问题