2016-10-19 18 views
9

mam ten kod:decltype dla przeciążonej funkcji członka

struct Foo 
{ 
    int print(int a, double b); 
    int print(int a); 
    void print(); 
    void print(int a, int b, int c); 

    void other(); 
}; 

mogę zadzwonić

decltype(&Foo::other) 

ale wzywającą

decltype(&Foo::print) 

koniec z błędem, co jest dla mnie jasne.

Ale jak mogę bardziej dokładnie określić, która z czterech metod print, chcę rozwiązać na decltype?

chcę dalej korzystać z tego w

template <class MT> 
struct method_info; 

template <class T, class Res, class... Args> 
struct method_info<Res(T::*)(Args...)> 
{ 
    typedef std::tuple<Args&&...> args_tuple; 
    typedef T ClassType; 
    typedef Res RetVal; 
}; 



template <class MethodType> 
void func() { 
    typedef method_info<MethodType> MethodInfo; 
    ..... 
} 

func<decltype(&Foo::other)>(); 
.... 
+0

Co masz na myśli mówiąc "bardziej" bliżej "*? Jeśli funkcja jest przeciążona, musisz dokładnie określić, która wersja ma być używana. – NathanOliver

+0

Czy jest to adres [odniesienie] (http://pl.cppreference.com/w/cpp/language/overloaded_address), którego szukasz? – UKMonkey

Odpowiedz

5

Więcej „ściśle”, o ile rozumiem, oznacza, że ​​chcesz określić argumenty funkcji z print. Oznacza to na przykład, że wybierasz int, int, a następnie zwracasz typ wyniku Foo{}.print(int{},int{}), a następnie konstruujesz wskaźnik funkcji ze wszystkich dostępnych informacji.

Oto szablon alias który robi to za Ciebie w sposób ogólny:

template<typename ... Args> 
using ptr_to_print_type = decltype(std::declval<Foo>().print(std::declval<Args>() ...)) (Foo::*)(Args ...); 

Można również użyć std::result_of zamiast std::declval rzeczy, ale lubię je bardziej.

Można użyć powyższego jako

func<ptr_to_print_type<int,int> >(); 

EDIT: jak zadawane przez @JavaLover, która btw wydaje się nieodpowiedniej nazwy dla takiej strasznej C++ :-) cholera, tu jest taka sama jak powyżej używając std::result_of ( niesprawdzone obecnie testowane i źle):

//------ does not compile for overloaded functions -------- 
template<typename ... Args> 
using ptr_to_print_type = std::result_of_t<decltype(&Foo::print)(Foo, Args ...)> (Foo::*)(Args ...) 
//------ does not compile for overloaded functions -------- 

można dodatkowo streszczenie dala Foo b nie jest to print (chyba że używasz makr).

+0

To jest najlepszy post, który znalazłem po kilkugodzinnym wyszukiwaniu. Podziękować. Czy możesz podać również przykład 'std :: result_of'? – javaLover

+1

@javaLover: dzięki. Dokonałem edycji. – davidhigh

+0

Dziękuję bardzo. W nowej wersji 'std :: result_of', kompilator nie może jednak rozwiązać przeciążonej funkcji. Oto [wersja demo] (http://coliru.stacked-crooked.com/a/c75739a460787e0e) i [kopia zapasowa] (http://ideone.com/3vPkzd). To jest zagubione w '(& Foo :: print)'. Jeśli zamienię linię 'version2' na starą linię' version1', to zadziała. – javaLover

3

nie wiesz o dokładnej składni, ale w przypadku nazwy metody przeciążeniem, oddasz wskaźnik; coś

static_cast<void(Foo::*)(int, int, int)>(&Foo::print); 

W jesteś zainteresowany tylko w typie, powinna być wartość szablon obsady

void(Foo::*)(int, int, int) 
Powiązane problemy