不,您不能使lambda超载!
lambda是anonymous functors(即未命名的函数对象),而不是简单的函数。因此,不可能使那些对象过载。
您基本上想做的几乎是
p.2
这是不可能的,因为不能在C ++中重用相同的变量名。
但是,在c++17中,我们拥有if constexpr
,通过它可以实例化在编译时唯一的唯一分支。
意味着可能的解决方案是:
- 一个variabe template lambda。或
- 通用lambda并使用
decltype
查找参数的类型
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
检查。(贷方 @NathanOliver )
使用variabe template可以执行类似的操作。 (See a live demo online)
if constexpr
并称呼它
#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];
}
};
使用通用lambda(自c++14起),上述内容将为:(See a live demo online)
int r = translate<int>(line[0]);
int c = translate<char>(line[1]);
并像现在一样调用lambda:
#include <type_traits> // std::is_same_v
constexpr auto translate = [](auto idx)
{
if constexpr (std::is_same_v<decltype(idx),0 };
return table[idx];
}
else if constexpr (std::is_same_v<decltype(idx),7} };
return table[idx];
}
};
,
Lambda基本上是本地定义函子的语法糖。据我所知,它们永远不会被重载以使用不同的参数来调用。请注意,每个lambda表达式都具有不同的类型,因此即使撇开即时错误,您的代码也无法按预期工作。
但是,您可以定义带有重载operator()
的函子。如果可能的话,这将是您从lambda上获得的确切结果。您只是没有简洁的语法。
类似的东西:
void read()
{
static std::string line;
struct translator {
int operator()(int idx) { /* ... */ }
int operator()(char x) { /* ... */ }
};
translator translate;
std::getline(std::cin,line);
int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));
std::cout << r << c << std::endl;
}
,
因此,重载名称的规则仅适用于某些类型的函数名称查找(免费和方法)。
Lambda不是函数,它们是带有函数调用运算符的对象。因此,在两个不同的lambda之间不会发生过载。
现在,您可以获得重载解析以使用功能对象,但仅在单个对象的范围内。然后,如果有多个operator()
,则可以在它们之间进行重载解析。
但是,λ显然没有办法拥有多个operator()
。我们可以编写一个简单的(在c++17中)实用程序类来帮助我们:
template<class...Fs>
struct overloaded : Fs... {
using Fs::operator()...;
};
和推论指南:
template<class...Fs>
overloaded(Fs...) -> overloaded<Fs...>;
使用这两个,我们可以重载两个lambda:
static std::string line;
std::getline(std::cin,line);
auto translate_int = [](int idx){
constexpr static int table[8] {7,0};
return table[idx];
};
auto translate_char = [](char c) {
std::map<char,int> table { {'a',7} };
return table[c];
};
auto translate = overloaded{ translate_int,translate_char };
int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));
完成。
在c++14和c++11中都可以写作overloaded
,但是需要更多的工作并且不够优雅。一旦意识到了问题,找到与您的特定编译器支持的C ++功能相匹配的解决方案就不难了。
本文链接:https://www.f2er.com/3163955.html