我正在开发一个GUI框架,我希望所有元素都由最多8个字符的ascii字符串标识(或者7可以)。
每次触发一个事件(有些只是点击,但有些是连续的),框架会使用id及其值回调客户端代码。
我可以使用实际的字符串和strcmp(),但我希望它非常快(对于移动设备),所以我想使用char常量(例如int id ='BTN1';)所以你会成为做一个int比较来测试id。但是,4个字符不够可读。
我尝试了一项实验,例如 - long int id = L'abcdefg';
...但看起来char常量只能容纳4个字符,并且唯一能产生long int char常量的东西就是你的4个字符宽度的两倍,而不是两倍的容量字符。我在这里错过了什么吗?
我想让编写客户端代码的人轻松一点。 gui存储在xml中,因此id是从字符串加载的,但是会在客户端代码中写入常量来比较这些常量。
所以,它的长期和短期是,我正在寻找一种跨平台的方式快速进行7-8字符比较,任何想法?
答案 0 :(得分:4)
一种可能性是将您的ID定义为64位整数和8个字符的字符串的并集:
union ID {
Int64 id; // Assuming Int64 is an appropriate typedef somewhere
char name[8];
};
现在你可以做以下事情:
ID id;
strncpy(id.name, "Button1", 8);
if (anotherId.id == id.id) ...
答案 1 :(得分:4)
您确定这不是过早优化吗?您是否已经分析了另一个纯粹来自字符串比较的GUI框架?为什么你这么确定字符串比较会太慢?当然你没有做 许多字符串比较。另外,考虑strcmp应该有一个接近最优的实现,可能是为你正在编译的CPU量身定制的组件。
无论如何,其他框架只使用命名整数,例如:
static const int MY_BUTTON_ID = 1;
您可以考虑相反,完全避免字符串问题。或者,您可以简单地编写一个辅助函数来将const char [9]转换为64位整数。这应该接受一个以空字符结尾的字符串“喜欢如此”,最多8个字符(假设您打算丢弃空字符)。然后你的程序传递64位整数,但程序员正在处理字符串。
编辑:这是一个将字符串转换为数字的快速函数:
__int64 makeid(const char* str)
{
__int64 ret = 0;
strncpy((char*)&ret, str, sizeof(__int64));
return ret;
}
答案 2 :(得分:1)
易于获得预卷组件
获胜的binary search tree - 您从大多数STL实现的set和map中获得了red-black树,因此您可能需要考虑这一点。
当你在很多地方移动容器节点时(在一般情况下),STL容器的Intrusive versions表现得更好 - 但是它们有很多警告。
具体意见 - 第一选择
如果我是你,我会坚持使用64位整数类型并将其捆绑在一个侵入式容器中并使用boost提供的库。但是,如果您是这类新手,那么使用stl :: map它在概念上更容易掌握,并且它有更少的资源泄漏机会,因为有更多的文献和指南可用于这些类型的容器和最佳实践。
备选方案2
我想要解决的问题是:有一个映射到句柄的全局命名方案。您可以创建名称到句柄的映射,以便您可以使用名称来检索句柄:
// WidgetHandle is a polymorphic base class (i.e., it has a virtual method),
// and foo::Luv implement WidgetHandle's interface (public inheritance)
foo::WidgetHandle * LuvComponent =
Factory.CreateComponent<foo::Luv>( "meLuvYouLongTime");
....
.... // in different function
foo::WidgetHandle * LuvComponent =
Factory.RetrieveComponent<foo::Luv>("meLuvYouLongTime");
替代方案2是IPC的常用习惯用法,您可以在一个进程中创建IPC类型的管道,并且可以要求内核按名称检索管道的另一端。
答案 3 :(得分:1)
string interning的概念对此问题很有用,将字符串比较转换为指针比较。
答案 4 :(得分:0)
我看到代码中易于读取的标识符与传递的表示之间存在区别。
您可以使用枚举类型(或常量的大头文件)来表示标识符吗?根据您的意愿,枚举类型的名称可以是长的和有意义的,并且仍然适合(我猜)几个字节。
答案 5 :(得分:0)
在C ++ 0x中,您将能够使用user-defined string literals,因此您可以添加7chars..id
或"7chars.."id
之类的内容:
template <char...> constexpr unsigned long long operator ""id();
constexpr unsigned long long operator ""id(const char *, size_t);
虽然我不确定你可以使用constexpr
作为第二个。