C++基于输入参数的返回类型推断

C++ Return Type Deduction Based on Input Parameters

本文关键字:参数 返回类型 输入 于输入 C++      更新时间:2023-10-16

我正在创建一个可以处理多种形式的数据的"知识处理器"。我计划支持的数据形式是文本、视觉和听觉。每个都可以分别通过文本、视觉和音频表示。因此,每个"知识"或数据都以称为"know_t"的结构表示。

#define VISUAL 0
#define AUDIO  1
#define TEXT   2
struct 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 宏表示。

说到重点,我正在为处理器编写搜索算法。这些类型(视觉、音频和文本)中的每一种都可以用"原型"形式表示。例如,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函数。问题是,随着数据类型的变化,返回类型也会发生变化

到目前为止,我已经为 == 运算符编写了以下代码,但我的编译器(带有 -std=c++11 的 GCC 4.8.1)似乎不喜欢它。

#define test(in) in.type == VISUAL ? in.visual_value : 
                 in.type == AUDIO  ? in.audio_value  : 
                 in.type == TEXT   ? in.text_value   : NULL
bool 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 { // because 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; // or something
}

请注意,根据 [global.names],您的type是无效的标识符:

包含双下划线 __ 或以下划线后跟大写字母开头的每个名称 字母 (2.12) 保留给实现以供任何用途使用。

最后,这可能不是一个好的存储数据类型。考虑使用:

using search_t = boost::variant<visual_t, audio_t, std::string>;