这是 this SO question的变体。我有一个重载函数,它接受不同类型的参数并返回不同的类型:
struct mystruct {
auto f (int x, int y) -> int;
auto f (std::string x, int y) -> float;
};
函数f
需要使用其中一个参数专门调用自身多次。
我想定义一个专门用于参数y
的函数,这是我想要的g(z) = f(z,y)
。返回类型g
及其唯一参数z
变量的类型,但两种情况下的实现都相同。
我能找到的这种情况的最佳实现是重载lambda函数:
template <class F1, class F2>
struct overload_set : F1, F2
{
overload_set(F1 f1, F2 f2) : F1(f1), F2(f2) {}
using F1::operator();
using F2::operator();
};
template <class F1, class F2>
overload_set<F1, F2> overload(F1 f1, F2 f2) {
return overload_set<F1, F2>(f1, f2);
};
struct mystruct {
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
auto g = overload (
[=]( int z ) -> int {return f(z,y);},
[=]( std::string z) -> float { return f(z,y); }
);
if ( x == 0 ) {
std::cout << g("this string") << "\n";
return 0;
}
if ( x == 1 ) return y;
return 7;
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
按预期工作,但似乎有点矫枉过正。它似乎是一个简单的预处理器宏形式
#define k(z) f(z,y)
也会奏效。有没有一种很好的方法来实现这一目标?
答案 0 :(得分:1)
不确定这是否是您尝试做的,但这是一个有效的(c ++ 14)示例:
#include <iostream>
struct mystruct {
static auto f (int x, int y) -> int {
std::cout << "f(" << x << "," << y << ")" << std::endl;
auto g = [=](auto z) -> decltype(mystruct::f(z, y)) {
return mystruct::f(z, y);
};
if (x < 1)
g("end");
else
g(x - 1);
}
static auto f (std::string x, int y) -> float {
std::cout << "f(\"" << x << "\"," << y << ")" << std::endl;
}
};
int main() {
mystruct::f(10, 1);
}
输出:
f(10,1) f(9,1) f(8,1) f(7,1) f(6,1) f(5,1) f(4,1) f(3,1) f(2,1) f(1,1) f(0,1) f("end",1)
答案 1 :(得分:0)
我错过了什么吗?
这产生了相同的答案,我认为更清楚一点:
#include <string>
#include <iostream>
struct mystruct
{
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
switch(x)
{
case 0: {
auto g = [=](auto...args) { return f(args..., y); };
std::cout << g("this string") << "\n";
return 0;
} break;
case 1: {
return y;
} break;
default:
return 7;
}
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
也许实际上有更多的切换案例,并且需要在g
声明之上悬挂switch
?