在C+;中的头文件中创建和填充映射+; 似乎C++没有办法做到这一点,但我希望我错了。

在C+;中的头文件中创建和填充映射+; 似乎C++没有办法做到这一点,但我希望我错了。,c++,maps,C++,Maps,我想做的是在头文件中创建一个映射(在本例中是将一组字符串映射到另一组字符串,而不是数据类型真正重要),以便多个源文件可以直接访问该映射 现在,我只是在头文件中定义了一个函数,并在源文件中实现了这个函数,它基本上实现了这个确切的函数,但我更喜欢使用映射,因为这样我就可以一眼看到键/值是什么 我遇到的问题是,填充映射需要可执行代码,而我不能直接将其放入头文件中。有什么好的方法来实现我正在做的事情吗?< P>你可以在C++ 11中使用一个初始化列表: 但这并不能解决问题。如果不想在头文件中对其进行初

我想做的是在头文件中创建一个映射(在本例中是将一组字符串映射到另一组字符串,而不是数据类型真正重要),以便多个源文件可以直接访问该映射

现在,我只是在头文件中定义了一个函数,并在源文件中实现了这个函数,它基本上实现了这个确切的函数,但我更喜欢使用映射,因为这样我就可以一眼看到键/值是什么


我遇到的问题是,填充映射需要可执行代码,而我不能直接将其放入头文件中。有什么好的方法来实现我正在做的事情吗?

< P>你可以在C++ 11中使用一个初始化列表:

但这并不能解决问题。如果不想在头文件中对其进行初始化,则很可能会出现链接器错误(多符号定义)

你可以: 1.使用extern关键字并在cpp文件中将其初始化为全局变量。
2.您可以将其设置为类内的静态变量(但仍在cpp文件中对其进行初始化)。

有几种方法可以做到这一点

您可以在头文件中声明变量,但需要在cpp文件中定义它…

// FOO.H STARTS HERE
#include <map>
#include <string>

extern std::map<std::string, std::string> my_map;
// FOO.H ENDS 

// FOO.CPP STARTS HERE
#include <iostream>

#include "foo.h"

std::map<std::string, std::string> my_map = {
  { "Cat", "Feline" },
  { "Dog", "Canine" },
  { "Fish", "Fish" }
};

int main (void) {
  for (auto i = my_map.begin(); i != my_map.end(); ++i) {
    std::cout << "A " << i->first << " is a " << i->second << std::endl;
  }

  return 0;
}

// FOO.CPP ENDS HERE
//FOO.H从这里开始
#包括
#包括
外部标准::映射我的映射;
//完
//FOO.CPP从这里开始
#包括
#包括“foo.h”
标准::映射我的映射={
{“猫”,“猫”},
{“狗”,“狗”},
{“鱼”,“鱼”}
};
内部主(空){
for(自动i=my_-map.begin();i!=my_-map.end();++i){

std::cout这里有一个不使用C++11的解决方案。这个示例还使用了三个文件来“证明”它是有效的

如果不打算更改映射,则应将初始化从foo.cpp移到foo.h并设为const

福安
//FOO.H从这里开始
#包括
#包括
#包括
typedef std::对字符串对;
常量字符串对映射开始值[]={
猫、猫、,
“狗”、“犬科动物”),
stringpair\u t(“鱼”、“鱼”)
};
const int map_start_values_size=sizeof(map_start_values)/sizeof(map_start_values[0]);
外部标准::映射我的映射;
//FOO.H到此结束
foo.cpp
//FOO.CPP从这里开始
#包括
#包括“foo.h”
映射我的映射(映射开始值,映射开始值+映射开始值大小);
int MAIN 2(无效);
内部主(空){
for(std::map::const_迭代器i=my_map.begin();i!=my_map.end();++i){

std::cout我将此视为一个挑战——是否有使用C++03语法的仅头部的解决方案

答案是“是”:


请注意,我并不推荐这个解决方案。只是把它作为一个有趣的可能性来展示。

extern
是你的朋友。你能详细介绍一下吗?全局变量是你的敌人。不幸的是,我的公司还不支持C++11,而且它看起来不会很快出现。我想我还是坚持我的if-else语句吧r现在。我可能会创建一个以映射作为其唯一成员的类,并将其填充到构造函数中,但这肯定不是一个优雅的解决方案。这正是我所寻找的答案,可惜我还不能在我的环境中使用C++11:(检查我的另一个答案。这可以不用C++11完成,但它有点难看。谢谢你解释如何使用extern。这是一个更普遍的答案变体!是的,这一个在我的环境中工作。我刚刚意识到我不能使用[]操作符访问元素tho,因为映射是常量,我必须使用。at()或者迭代器。这可能是一个愚蠢的问题,但是有没有办法解决[]用一个const映射来工作?它看起来是一种更优雅的访问地图的方法。最近我在Python中进行了编码,所以我完全知道你从哪里来。C++地图实际上不适合这种手提式。答案是不。代码:STM:::运算符[](int)< /Cord>必须修改数组。<代码>:ST::MAP::()
实际上是一个C++11方法,但如果它对您有效,那就太好了,因为在我看来,它正是您在这里寻找的,没有理由回避它。我不确定您为什么要回避调用命名方法。这只是需要记住的一件事,不是什么大问题,但离超级干净的inter还有一步之遥我想这个解决方案会很好,但是现在所有的对都可以在.h文件中,不需要扫描C++函数来确定对是什么。
// FOO.H STARTS HERE
#include <map>
#include <string>

const std::map<std::string, std::string> my_map = {
  { "Cat", "Feline" },
  { "Dog", "Canine" },
  { "Fish", "Fish" }
};

// FOO.H ENDS HERE

// FOO.CPP STARTS HERE
#include <iostream>

#include "foo.h"

int main (void) {
  for (auto i = my_map.begin(); i != my_map.end(); ++i) {
    std::cout << "A " << i->first << " is a " << i->second << std::endl;
  }

  return 0;
}

// FOO.CPP ENDS HERE
// FOO.H STARTS HERE
#include <map>
#include <string>
#include <vector>

typedef std::pair<std::string, std::string> stringpair_t;
const stringpair_t map_start_values[] = {
  stringpair_t("Cat", "Feline"),
  stringpair_t("Dog", "Canine"),
  stringpair_t("Fish", "Fish")
};

const int map_start_values_size = sizeof(map_start_values) / sizeof(map_start_values[0]);

extern std::map <std::string, std::string> my_map;

// FOO.H ENDS HERE
// FOO.CPP STARTS HERE
#include <iostream>

#include "foo.h"

std::map<std::string, std::string> my_map (map_start_values, map_start_values + map_start_values_size);

int main2(void);

int main (void) {
  for (std::map<std::string, std::string>::const_iterator i = my_map.begin(); i != my_map.end(); ++i) {
    std::cout << "A " << i->first << " is a " << i->second << std::endl;
  }

  main2();

  return 0;
}

// FOO.CPP ENDS HERE
// FOO2.CPP STARTS HERE
#include "foo.h"

#include <iostream>

int main2 (void) {
  for (std::map<std::string, std::string>::const_iterator i = my_map.begin(); i != my_map.end(); ++i) {
    std::cout << "A " << i->first << " is a " << i->second << std::endl;
  }

  return 0;
}

// FOO2.CPP ENDS HERE
// GlobalMap.hpp
#include <map>

typedef std::map<std::string, std::string> GMap;

inline
GMap & globalMap()
{
    static GMap theMap;
    static bool firstTime = true;
    if(firstTime)
    {
        firstTime = false;
        theMap["Cat"] = "Feline";
        theMap["Dog"] = "Canine";
        theMap["Guppy"] = "Fish";
    }
    return theMap;
}
#include <iostream>
#include "GlobalMap.hpp"
int main()
{
    for(
        GMap::const_iterator it = globalMap().begin();
        it != globalMap().end();
        ++it)
    {
        std::cout << '[' << it->first << "]=" << it->second << std::endl;
    }
   return 0;
}
[Cat]=Feline
[Dog]=Canine
[Guppy]=Fish