1
我有这个代码依赖于SFINAE和默认的模板参数。它的工作原理正如所料,除了最后两注释行:函数模板重载的地址
#include <tuple>
#include <iostream>
using namespace std;
template<typename T> void push(T val){
cout<<val<<endl;
}
template<typename T> T to(){
T dummy;
cin>>dummy;
return dummy;
}
template<typename T, T> class function_proxy{
static_assert(sizeof(T)!=sizeof(T), "Error: function_proxy works with functions (duh)");
};
template<typename Return, typename... Args, Return(*func)(Args...)> class function_proxy<Return(*)(Args...), func>{
static Return call(Args... args){
return func(args...);
}
template<typename... retrieved> static Return call(retrieved... read){
return call(read..., to<typename tuple_element<sizeof...(read), tuple<Args...> >::type >());
}
public:
template<typename Ret=Return, typename enable_if<!is_void<Ret>::value, int>::type=0>
static int wrapper(){
push(call());
return 1;
}
template<typename Ret=Return, typename enable_if<is_void<Ret>::value, int>::type=0>
static int wrapper(){
call();
return 0;
}
};
int f(int arg){ return arg*3; }
void g(){ cout<<"g does nothing"<<endl; }
int main(){
//SFINAE works nicely
function_proxy<decltype(&f), &f>::wrapper();
function_proxy<decltype(&g), &g>::wrapper();
//Here it doesn't, even though there should be no ambiguity:
//function_proxy<decltype(&f), &f>::wrapper;
//function_proxy<decltype(&g), &g>::wrapper;
}
你可以看到,当我打电话的模板功能,SFINAE它的工作。但是,当我尝试使用唯一不合格的函数地址时,g ++会抱怨它无法解析重载函数的地址。
有没有办法解决这个问题,而不明确告诉这些重载函数的第一个模板参数?理论上,这是多余的。另外,我的代码使用这个辅助类是非常通用的,所以这里的f
和g
的返回类型可能不是那么微不足道。
我明白了。关键是我认为这绝对是安全的,当你以这种方式采取地址时,拥有SFINAE是有意义的。有没有机会在未来的标准中看到这种情况? – 2012-04-24 06:53:48
@LorenzoPistone - 谁知道。 SFINAE的这种内省式使用不是原来建议的重点,它集中在平衡诊断,易用性(模板和函数调用)以及易于编译器实现(类型推导,重载解析)上。其他一些语言确实具有标准的自省功能,也许C++有一天会跟上诉讼。或者,未来可能会给我们带来更多的SFINAE。 – 2012-04-24 14:20:25