假设用户定义的下列功能的一些子集:选择最优惠功能通过标签继承
void f(int) {}
void g(int) {}
void h(int) {}
// ...
你的任务是编写一个函数call_best(int)
这就要求从声明的上面列表中的第一个函数(你然后可以假定它也被定义)。你是怎样做的?
假设用户定义的下列功能的一些子集:选择最优惠功能通过标签继承
void f(int) {}
void g(int) {}
void h(int) {}
// ...
你的任务是编写一个函数call_best(int)
这就要求从声明的上面列表中的第一个函数(你然后可以假定它也被定义)。你是怎样做的?
首先,我们定义一个优先级。
template<unsigned P> struct priority : priority<P-1> {};
template<> struct priority<0> {};
它可以用来给一个总订单上的功能如下:
template<class Int> auto call_best(Int i, priority<2>) -> decltype(f(i)) { return f(i); }
template<class Int> auto call_best(Int i, priority<1>) -> decltype(g(i)) { return g(i); }
template<class Int> auto call_best(Int i, priority<0>) -> decltype(h(i)) { return h(i); }
void call_best(int i) { call_best(i, priority<2>{}); }
的Int
模板参数和decltype()
确保只有定义函数争夺被称为(关键字SFINAE )。 priority
标签类允许我们选择其中最好的一个。
请注意,SFINAE部件仅适用于您有至少有一个参数您可以模板。如果有人有关于如何避免这种情况的想法,请告诉我。
如果您遵循给出函数推导返回类型的惯例(即auto
/decltype(auto)
),则您的代码将起作用。这只能在C++ 14中完成,其中具有推导的返回类型的函数在定义之前不能使用(即使在未评估的操作数中),否则导致替换失败。这是你的例子,在铛3.5工作,但不幸的是不在g ++ 4.9。
template<unsigned P> struct priority : priority<P-1> {};
template<> struct priority<0> {};
// ********
auto f(int);
auto g(int);
auto h(int) { std::cout << "h()"; }
// ********
template<class Int> auto call_best(Int i, priority<2>) -> decltype(f(i)) { return f(i); }
template<class Int> auto call_best(Int i, priority<1>) -> decltype(g(i)) { return g(i); }
template<class Int> auto call_best(Int i, priority<0>) -> decltype(h(i)) { return h(i); }
void call_best(int i) { call_best(i, priority<2>{}); }
int main()
{
call_best(0); // calls h()
}
只是好奇,有什么用例呢? – 2014-10-03 09:36:52
所有这些功能都已定义。 – 2014-10-03 09:55:50
@NicolasHolthaus:我认为OP想要做一些类似于[调用免费函数而不是方法的方法](http://stackoverflow.com/questions/21441803/)调用一个免费函数而不是方法 - 如果它不存在) – Jarod42 2014-10-03 10:01:15