我们有一些将静态数据成员公开为公共成员的类,例如
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时正在创建的类的临时对象,是否保证始终具有定义的行为?
答案 0 :(得分:1)
似乎您可能正在使用类名实现某种反射机制。为什么不真正地获取类名作为名称?
看看:
Can I obtain C++ type names in a constexpr way?
接受的答案那里允许编写get_name<A>()
,并得到一个字符串(_view),它是 “A”。 get_name<B>()
将是“ B”,依此类推。这可能对您有用,因为:
答案 1 :(得分: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;
}
答案 2 :(得分:0)
保证只能工作
A.cpp
)但是,您在玩火...而不是根据静态初始化顺序,最好使用在静态成员函数中定义的 local static 变量;即
// 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;
}
保证此方法有效,因为 local 静态变量是在首次使用时初始化的(甚至在C ++ 11中甚至针对多线程问题也得到了自动保护)。