从其它类的静态数据成员地图初始化

问题描述 投票:2回答:3

我们已经暴露了静态数据成员作为公众成员像类

class A{
public:
    static const string NAME;
    //Other class specific methods
};

而类似的B类和其他几个班。

如果我要创建一个映射像

static const map<string, string> versionMap = {{A().NAME, "Aa"},
                                               {B().NAME, "Bb"}
                                              };

正在创建的类临时对象在创建versionMap,是保证已定义的行为所有的时间?

c++ c++11
3个回答
1
投票

好像你可能会实施某种形式的反射机制,与类名。为什么居然没有得到类名,姓名?

看一下:

Can I obtain C++ type names in a constexpr way?

接受的答案有让你写get_name<A>()并得到一个字符串(_view),这是“A”。而get_name<B>()将“B”等等。这可能是你的情况是有用的,因为:

  1. 没有动态分配的数据。
  2. 任何物体的任何建设(虽然@ jhill515也给你)
  3. 无需静态成员 - 这可以用你甚至不控制类的工作!

0
投票

当你定义一个类的静态成员,不管该类是否被实例化时,该成员是通过内存访问。在这种情况下,因为他们是公众的成员,使用字符串本身作为键是完全有效的。

这就是说,你的静态常量成员需要的类定义,通常像后进行初始化:

class Foo { static const int foo; };
const int Foo::foo = 42;

为了您的静态地图例如,你需要记住的是,如果作为一个类成员的地图也必须进行类似初始化。这里有一个工作示例:

// Compiled with g++ --std=c++17 -Wall -Wextra -Werror ConstStaticMapExample.cpp -o ConstStaticMapExample
#include <iostream>
#include <string>
#include <map>

class A
{
public:
  static const std::string NAME;
  //Other class specific methods
};
const std::string A::NAME = "foo";

class B
{
public:
  static const std::string NAME;
  //Other class specific methods
};
const std::string B::NAME = "bar";

class C
{
public:
  static const std::map<std::string, std::string> versionMap;
  // More definitions
};
const std::map<std::string, std::string> C::versionMap = {{A::NAME,"aA"},{B::NAME,"bB"}}; // Reversed for explanation

int main(int,char**)
{
  // local static
  static const std::map<std::string, std::string> versionMap = {{A::NAME,"Aa"},{B::NAME,"Bb"}};
  std::cout << "LOCAL STATIC EXAMPLE:" << std::endl;
  for(auto mpair : versionMap)
  {
    std::cout << "Key: " << mpair.first << "\tVal: " << mpair.second << std::endl;
  }

  // class member static
  std::cout << "CLASS MEMBER STATIC EXAMPLE:" << std::endl;
  for(auto mpair : C::versionMap)
  {
    std::cout << "Key: " << mpair.first << "\tVal: " << mpair.second << std::endl;
  }

  return 0;
}

Gist


0
投票

这是保证只有工作

  • 地图被在所述静态成员的定义相同的编译单元中定义(例如A.cpp
  • 地图被静态数据成员的定义之后定义

你不过玩火...而不是依赖静态初始化顺序很可能是更好的使用静态成员函数中定义的本地静态变量上;即

// File A.h

struct A {
    static const std::string& NAME();
};

// File Map.cpp

std::map<std::string, std::string> x{{A::NAME(), "A"}};

// File A.cpp

static const std::string& A::NAME() {
    static std::string x = "A string";
    return x;
}

这种方法是保证工作,因为当地的静态变量在第一次使用初始化(甚至自动C ++ 11的保护对多线程的问题)。

© www.soinside.com 2019 - 2024. All rights reserved.