我另外提供一个答案,与之前的完全不同,可以解决您的问题。
这个想法是使用另一个类,并正确地混合显式和非显式构造函数。
下面是一个最小化、可工作的示例:
#include <functional>
#include <iostream>
template<class C, int(C::*M)()>
struct Arg {
std::function<int(C*)> fn;
Arg(int i): fn{[i](C*){ return i; }} { }
explicit Arg(): fn{[](C* c){ return (c->*M)(); }} { }
};
struct S {
int f() { return 1; }
int h() { return 2; }
void g(int arg0,
Arg<S, &S::f> arg1 = Arg<S, &S::f>{},
Arg<S, &S::h> arg2 = Arg<S, &S::h>{})
{
std::cout << "arguments" << std::endl;
std::cout << "arg0: " << arg0 << std::endl;
std::cout << "arg1: " << arg1.fn(this) << std::endl;
std::cout << "arg2: " << arg2.fn(this) << std::endl;
}
};
int main() {
S s{};
s.g(42, 41, 40);
s.g(0);
}
这个例子展示了如何混合使用默认参数和非默认参数。
很容易就可以修改它,让
g
成为一个没有参数的函数,就像原问题中那样。
我相信这个例子还可以进一步改进,得到比现在更好的结果,但是这已经是一个不错的起点了。
下面是应用于原问题的解决方案:
#include <functional>
template<class C, int(C::*M)()>
struct Arg {
std::function<int(C*)> fn;
Arg(int i): fn{[i](C*){ return i; }} { }
explicit Arg(): fn{[](C* c){ return (c->*M)(); }} { }
};
struct S {
int f() { return 1; }
int g(Arg<S, &S::f> arg = Arg<S, &S::f>{}) {
return arg.fn(this);
}
};
int main() {
S s{};
return s.g();
}
这就是全部内容了,甚至可以不用 static
方法或全局变量实现。
当然,我们可以以某种方式使用 this。这只是需要对语言进行一些弯曲处理...
int g() { return g(f()); }
,对吧?至少在实际代码中,这样做可能更有意义。当然,在这里它只适用于你的g
函数中只有一个return
语句。 - skypjack