1
SFINAE 및 기본 템플릿 인수를 사용하는이 코드가 있습니다. 예상대로 지난 2 개 주석 라인을 제외하고 작동합니다함수 템플릿 오버로드 주소 가져 오기
#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를 갖는 것이 합리적이라고 생각합니다. 이것이 미래의 표준에서 일어날 수있는 기회가 있습니까? –
@LorenzoPistone - 누가 압니다. SFINAE의 이러한 내성적인 사용은 진단, 쉬운 사용 (템플릿 및 함수 호출) 및 컴파일러 구현의 용이성 (형식 공제, 과부하 해결)에 중점을 둔 원래 제안의 일부가 아니 었습니다. 다른 언어들도 표준 인트로 스펙 션 기능을 가지고 있으며 아마도 C++이 언젠가 그 소송을 따를 것입니다. 또는 미래가 우리에게 더 많은 SFINAE를 가져다 줄 수 있습니다. –