2016-11-04 1 views
1

std::declval<T>() 뒤에 메소드 이름을 템플릿 매개 변수로 전달하는 방법이 있습니까?C++ 11 - std :: decl <T>() 메소드의 이름

지금까지,이 있습니다

template<typename T, typename ... Args> 
struct MethodInfo 
{ 
    using type = decltype(std::declval<T>().foo(std::declval<Args>() ...)) (T::*)(Args ...); 
}; 

을하지만 난 "foo은"템플릿 parametr 싶습니다.

+0

요청하신 내용이 정확하지 않지만 [this] (http://coliru.stacked-crooked.com/a/0197cd774882606c)와 같은 것이 귀하의 요구 사항을 충족합니까? – TartanLlama

+0

@TartanLlama 아니요, 오버로드 된 메서드에 대해 작동하지 않기 때문에 –

답변

1

그것은 당신이 무엇을 요구 정확히 아니지만 나는이 다소 당신의 필요에 맞는 것 같아요 :

#include <type_traits> 
#include <tuple> 
#include <iostream> 

template<typename T, typename... Args> 
struct MethodInfo { 
    template<typename Ret> 
    static auto get(Ret(T::*)(Args...)) -> Ret(T::*)(Args...); 
}; 

struct Foo { 
    int foo(int); 
    int foo(int, int); 
}; 

int main() { 
    static_assert(std::is_same< 
         int(Foo::*)(int), 
         decltype(MethodInfo<Foo, int>::get(&Foo::foo)) 
          >::value, ""); 
} 

Demo

함수 이름이 형식이 아닌 템플릿 매개 변수이기 때문에 이것이 유일한 해결책이라고 생각합니다.

+0

그것은 내가 묻는 것이 아니지만,이 솔루션은 나의 것보다 낫다 ... 그것은 작동하고있다. 나는 그것을 preprocessor 매크로로 랩핑 할 수 있었다. 코드가 짧다. –

1
C++ (11)이 작업을 수행 할 수 있습니다에서

하지만, 거의 패배,이 클래스의 목적 :

template<typename T, typename U, U ptr, typename... Args> 
struct TypeOverload; 

template<typename T, typename U, typename... Args, U(T::* ptr)(Args...)> 
struct TypeOverload<T, U(T::*)(Args...), ptr, Args...> 
{ 
    using type = decltype((std::declval<T>().*ptr)(std::declval<Args>() ...)) (T::*)(Args ...); 
}; 

다음과 같이 사용이 될 것이기 때문에 :

using bar_t = TypeOverload<Foo, decltype(&Foo::bar), &Foo::bar, int, int>::type; 
static_assert(std::is_same<bar_t, void(Foo::*)(int,int)>::value, ""); 

demo


auto 템플릿 매개 변수가 C++ 17 인 경우, 그의 :

template<typename T, auto ptr, typename... Args> 
struct TypeOverload 
{ 
    using type = decltype((std::declval<T>().*ptr)(std::declval<Args>() ...)) (T::*)(Args ...); 
}; 

다음과 같이 당신은 그것을 사용하십시오 :

using bar_t = TypeOverload<Foo, &Foo::bar, int, int>::type; 
static_assert(std::is_same<bar_t, void(Foo::*)(int,int)>::value, ""); 

demo

+0

@TartanLlama 오른쪽, 잘못된 창에서 복사했습니다. 즉, 과부하에 대한 OP의 의견을 읽었으므로이 대답은 어쨌든 삭제해야 할 것입니다. – krzaq

+1

과부하를 처리해야 할 필요가 있는지 확실하지 않습니다. 모호성을 제거하려면 호출 사이트에서 'static_cast'를 사용해야합니다. 나는'foo'가 템플릿/과부하 된'operator()'를 가진 멤버 펑터가 될 수 있다고 생각합니다. 그것이 내 머리 꼭대기에서 생각할 수있는 유일한 방법입니다. – TartanLlama

+0

@krzaq 라이브 데모에서 과부하를 처리 할 수 ​​있습니다. 그러나 Visual Studio 2015에서는 컴파일이 안됩니다 :/-''TypeOverload ': 템플릿 매개 변수'Args '가 선언문과 호환되지 않습니다.' 'TypeOverload': 템플릿 인수가 너무 많습니다. –

관련 문제