在C++中制作动态文本可寻址列表
Making a dynamically text-addressable list in C++
在大多数脚本语言中,对象通常是项的集合,绑定到这些对象中的名称。例如(在Javascript中),假设我要初始化它:
colors = {
Blue: 0x0000FF; //Hex Values
Green: 0x00FF00;
Red: 0xFF0000;
}
在运行时,如果用户键入列出的颜色,我可以使用 colors["given_color"]
轻松返回相应的十六进制值。
但是,我将如何用C++或其他编译语言来表达一个甚至非常相似的机制?创建一个enum
只会在静态上有意义,在人为的例子中:
public enum colors{
CYAN = 0x00FFFF,
MAGENTA = 0xFF00FF,
YELLOW = 0xFFFF00
}
不能以任何方式用于查找相应的十六进制std::cin << givenColor;
话虽如此,我有哪些选项可以将std::string
转换为数据点、指针或函数指针?
您要查找的数据结构称为映射(或字典或关联数组)。在C++中,有std::map
总是排序的(通常实现为红黑树),std::unordered_map
通常更快,因为它使用哈希表(但内容是任意顺序)。
std::unordered_map<std::string, int> colors = {
{"blue", 0x0000FF},
{"green", 0x00FF00},
{"red", 0xFF0000}
};
std::string key = /* something */;
std::string value = colors[key];
回答评论中的问题:是的,您可以将任何您想要的东西存储在地图中。唯一的限制是,对于std::unordered_map
,密钥类型需要实现哈希函数并operator==
,而对于std::map
,密钥类型需要实现operator<
。值类型可以是任何值。
您可以使用std::unordered_map
:
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<std::string, unsigned int> colors =
{
{"CYAN", 0x00FFFF},
{"MAGENTA", 0xFF00FF},
{"YELLOW", 0xFFFF00},
};
unsigned int retrieved_color = colors["CYAN"];
}
现在,如果您尝试将C++用作像JavaScript这样的动态语言,这让我有点困扰。如果你真的需要映射一个字符串,你从你无法控制的地方得到的,也许你从网络收到,或者类似的东西,这很好。这是要走的路。
但是,如果您只需要能够在代码中使用名称CYAN
,请将此解决方案与enum
进行比较:
obj.set_color(CYAN);
对
obj.set_color(colors["CYAN"]);
第一个在编译时解析,set_color
接收文本常量作为参数。
在第二个中,文字字符串"CYAN"
用于初始化临时对象std::string
,然后复制到堆分配的位置。然后计算这个字符串的哈希值(O(N),我相信字符串的大小,Java 在制作字符串哈希时只使用几个字符已经遇到了问题),然后有一个内存获取来获取实际值。最后,临时std::string
被解除分配。然后调用函数set_color
。
这笔额外费用与您的计划无关吗?或。但最终,您的最终产品中会累积多少无关紧要的额外成本?
将 C++ 的效率与重载运算符<<的轻松调试相结合,如下所示:
enum class colors {
CYAN = 0x00FFFF,
MAGENTA = 0xFF00FF,
YELLOW = 0xFFFF00
};
std::ostream& operator<<(std::ostream& os, colors c)
{
switch(c) {
case colors::CYAN : os << "cyan"; break;
case colors::MAGENTA : os << "magenta"; break;
case colors::YELLOW : os << "yellow"; break;
}
return os;
}
BOOST_AUTO_TEST_CASE(play_colors)
{
std::vector<colors> v { colors::CYAN, colors::YELLOW, colors::MAGENTA };
std::copy(begin(v), end(v), ostream_iterator<colors>(cout, ", "));
cout << endl;
}
预期输出(添加正确的标头后):
cyan, yellow, magenta,
- 从结构寻址时,MMAP变量的行为很奇怪
- 字节真的是最小可寻址单元吗
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- imread() 仍然返回空垫子,尽管在 openCV 4.0.0 中寻址正确
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- C++11右值引用寻址
- 对堆栈增长和寻址的困惑
- C++ std::find() 寻址返回向量的类函数时的意外行为
- 间接寻址运算符如何返回带有运算符重载的指针地址
- Adafruit NeoPixel库在寻址超过7个LED灯条时不起作用
- 在模板 SFINAE 约束中使用间接寻址级别会导致硬错误
- 错误:使用索引寻址和 Clang 的指令的操作数无效
- 是否可以寻址另一个网络中的服务器/客户端套接字?(C++)
- C++中的字节寻址算法
- 指针声明和间接寻址之间的区别
- 仅在使用间接寻址时调用虚函数 — 经典的早期绑定问题?
- C++ std::map 不同的键寻址同一索引
- Valgrind 错误:系统调用参数 epoll_pwait(sigmask) 指向不可寻址的字节
- 在C++中制作动态文本可寻址列表