我正在创建一个“知识处理器”,它可以处理多种形式的数据。我计划支持的形式包括文本、视觉和听觉数据。它们分别可以通过TEXT、VISUAL和AUDIO来表示。因此,每个“知识”或数据都将在一个名为“know_t”的结构中表示。
#define VISUAL 0#define AUDIO 1#define TEXT 2struct know_t { k_type_t type; text_k_t text_value; visual_k_t visual_value; audio_k_t audio_value;};
k_type_t 是从 int 定义的类型。它用于存储数据的“类型”,可以通过代码片段开头的#define宏来表示。
重点是,我正在为处理器编写一个搜索算法。这些类型VISUAL、AUDIO和TEXT可以用“原型”形式表示。例如,TEXT数据可以通过std::string表示。这种数据的原型形式将用于搜索知识数据库。为了便于搜索,我创建了一个名为“search_t”的结构来表示搜索操作。
struct search_t { k_type_t type; visual_t visual_value; audio_t audio_value; std::string text_value; bool operator == (const struct __search_t &in);};
现在这里的结构可能看起来几乎与上面的know_t结构完全相同,但它们实际上是非常不同的。例如,虽然“k_type_t”类型包含字符串的数据,如定义,std::string是用于搜索的数据形式。其他的数据形式也是如此。
我正在使用C++的unordered_map来完成搜索。ISO C++标准规定,要使unordered_map工作,需要为键类型(这里是search_t)提供哈希函数和“==”运算符。为此,我决定编写一个get_value函数,返回搜索结构的原型值。问题是随着数据类型的变化,返回类型也会变化。
到目前为止,我已经编写了以下代码,用于==运算符,但我的编译器(GCC 4.8.1 带 -std=c++11)似乎不喜欢它。
#define test(in) in.type == VISUAL ? in.visual_value : \ in.type == AUDIO ? in.audio_value : \ in.type == TEXT ? in.text_value : NULLbool search_t::operator == (const struct search_t &in) { auto getval_search = [](const search_t &in) -> decltype(test(in)) { if (in.type == __VISUAL__) return in.visual_value; if (in.type == __AUDIO__) return in.audio_value; if (in.type == __TEXT__) return in.text_value; } bool equal = (bool)((this->type) == in.type); if (!equal) return false; search_t tmp = *this; // bugfix if (getval_search(tmp) == getval_search(in)) return true;}
有什么办法可以修复这个问题吗?
回答:
是的。修复这个问题的一个简单方法是编写一个普通的==
比较:
struct search_t { // 因为C++ k_type_t type; visual_t visual_value; audio_t audio_value; std::string text_value; bool operator == (const search_t& in) const { return type == in.type && visual_value == in.visual_value && audio_value == in.audio_value && text_value == in.text_value; }};
如果真的只是基于类型,那么我想你可以这样做:
bool operator == (const search_t& in) const { if (type != in.type) return false; switch (type) { case __VISUAL__: return visual_value == in.visual_value; case __AUDIO__: return audio_value == in.audio_value; case __TEXT__: return text_value == in.text_value; default: return false; // 或者其他}
请注意,你的type
是无效的标识符,根据[global.names]规定:
每个包含双下划线__或以一个下划线后跟一个大写字母开头的名称(2.12)都被保留给实现用于任何用途。
最后,这可能不是一个适合存储的数据类型。考虑使用:
using search_t = boost::variant<visual_t, audio_t, std::string>;