How to overload a simple local lambda function?
SSE of original problem:
#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;
}
The error messages
error: conflicting declaration 'auto translate'
note: previous declaration as 'read()::<lambda(int)> translate'
Please don't mind not checking user input, this is an SSE.
No, you can not overload the lambda!
The lambdas are anonymous functors(i.e. unnamed function objects), and not simple functions. Therefore, overloading those objects not possible. What you basically trying to do is almost
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
Which is not possible, as the same variable name can not be reused in C++.
However, in c++17 we have if constexpr
by which one can instantiate the only branch which is true at compile time.
Meaning the possible solutions are:
decltype
for the if constexpr
check.(credits @NathanOliver)Using variabe template you can do something like. (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];
}
};
and call it like
int r = translate<int>(line[0]);
int c = translate<char>(line[1]);
Using generic lambda(since c++14), the above will be: (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];
}
};
and call the lambda as you do now:
int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));