c++ - 重载 lambda 函数

标签 c++ lambda overloading c++17 function-object

如何重载简单的本地 lambda 函数?

原始问题的SSE:

#include <iostream>
#include <map>

void read()
{
    static std::string line;
    std::getline(std::cin, line);

    auto translate = [](int idx)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    };

    auto translate = [](char c)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3},
                                             {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[c];
    };

    int r = translate(static_cast<int>(line[0]));
    int c = translate(static_cast<char>(line[1]));
    std::cout << r << c << std::endl;
}

int main()
{
    read();
    return 0;
}

错误信息

error: conflicting declaration 'auto translate'
note: previous declaration as 'read()::<lambda(int)> translate'

请不要介意不检查用户输入,这是一个 SSE。

最佳答案

不,你不能重载 lambda!

lambda 表达式为 anonymous functors (即未命名的函数对象),而不是简单的函数。因此,不可能重载这些对象。 你基本上想做的几乎是

struct <some_name>
{
    int operator()(int idx) const
    {
        return {}; // some int
    }
}translate; // >>> variable name

struct <some_name>
{
    int operator()(char idx) const
    {
        return {}; // some int
    }
}translate; // >>> variable name

这是不可能的,因为在 C++ 中不能重复使用相同的变量名。

<小时/>

但是,在 我们有if constexpr通过它可以实例化唯一在编译时为 true 的分支。

这意味着可能的解决方案是:

  • 单个variabe template lambda 。或
  • 通用 lambda 并使用 decltype 查找参数的类型 用于 if constexpr 检查。(来源 @NathanOliver)

使用variabe template你可以做类似的事情。 ( See a live demo online )

#include <type_traits> // std::is_same_v

template<typename T>
constexpr auto translate = [](T idx) 
{
    if constexpr (std::is_same_v<T, int>)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    }
    else if constexpr (std::is_same_v<T, char>)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[idx];
    }
};

并这样调用它

int r = translate<int>(line[0]);
int c = translate<char>(line[1]);
<小时/>

使用泛型 lambda(自 起),以上将是:( See a live demo online )

#include <type_traits> // std::is_same_v

constexpr auto translate = [](auto idx) 
{
    if constexpr (std::is_same_v<decltype(idx), int>)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    }
    else if constexpr (std::is_same_v<decltype(idx), char>)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[idx];
    }
};

并像现在一样调用 lambda:

int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));

关于c++ - 重载 lambda 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58700542/

相关文章:

c++ - 模板友元函数: wrong function called

c++ - 如何在不复制和粘贴整个类主体的情况下专门化模板?

java - 使用 Java Streams 返回单词出现的句子计数和列表

c++ - 在接受套接字连接时

c++ - 什么是 consteval?

amazon-web-services - 查询 AWS DynamoDB 以返回半径内的经纬度结果

python - lambda 比 python 中的函数调用慢,为什么

java - 如果我重载 equals 我仍然应该重写 java 中的 haschode 吗?

c++ 用c++重载虚函数警告?

c# - 方法 'METHOD' 没有重载需要 0 个参数