2016-07-19 13 views
7

I niedawno dowiedziałem się, że nie mogę:określania rodzajów parametr niezdefiniowanej funkcji

  1. Take the address of an undefined function
  2. Take the address of a templatized function with a type it would fail to compile for

Ale ja również niedawno dowiedziałem się, że możecall decltype to get the return type of said function

Tak więc niezdefiniowana funkcja:

int foo(char, short); 

Chciałbym wiedzieć, czy istnieje sposób, że mogę dopasować typy parametrów do typów w tuple. Jest to oczywiście pytanie dotyczące meta-programowania. Co ja naprawdę strzelanie na to coś jak decltypeargs w tym przykładzie:

enable_if_t<is_same_v<tuple<char, short>, decltypeargs<foo>>, int> bar; 

Czy ktoś może mi pomóc zrozumieć, w jaki sposób mogą być wykonane decltypeargs?

+4

@Barry To nie jest duplikat tego pytania, wszystkie odpowiedzi wymagają podania adresu mojej funkcji, co wyraźnie powiedziałem, że nie mogę tego zrobić, ponieważ jest nieokreślone. Otwórz ponownie. –

+0

Wątpliwości. Jak myślisz, dlaczego tego potrzebujesz? –

+0

@LightnessRacesinOrbit Tak Wątpię też. Właściwie nie dbam o niezdefiniowane funkcje. Ale byłoby mi bardzo pomocne, gdyby udało mi się uzyskać funkcję funkcji templatetycznej, która nie przetrwałaby SFINAE. –

Odpowiedz

3

Dla nie przeciążonych funkcji, wskaźników do funkcji i wskaźników do funkcji składowych, po prostu robi decltype(function) daje typ funkcji w nieocenionym kontekście, a ten typ zawiera wszystkie argumenty.

Tak, aby uzyskać typów argumentu w postaci krotki, wszystko czego potrzebujesz jest wiele specjalizacji:

// primary for function objects 
template <class T> 
struct function_args 
: function_args<decltype(&T::operator()> 
{ }; 

// normal function 
template <class R, class... Args> 
struct function_args<R(Args...)> { 
    using type = std::tuple<Args...>; 
}; 

// pointer to non-cv-qualified, non-ref-qualified, non-variadic member function 
template <class R, class C, class... Args> 
struct function_args<R (C::*)(Args...)> 
: function_args<R(Args...)> 
{ }; 

// + a few dozen more in C++14 
// + a few dozen more on top of that with noexcept being part of the type system in C++17 

Z tym:

template <class T> 
using decltypeargs = typename function_args<T>::type; 

Wymaga to pisanie decltypeargs<decltype(foo)>.


z C++ 17, będziemy mieli template <auto>, więc powyższe mogą być:

template <auto F> 
using decltypeargs = typename function_args<decltype(F)>::type; 

i chcesz dostać składnię decltypeargs<foo>.

+0

Wow mój umysł jest przepalony. Nie miałem pojęcia o rzeczy "decltype". Tak naprawdę pisałem odpowiedź na pytanie, w jaki sposób nie można tego zrobić. +1 Również nigdy nie widziałem 'auto' jako specyfikatora typu szablonu. Czy to jest po prostu doskonałe przekazywanie? –

+1

@ JonathanMee http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0127r2.html – Barry

+2

Czy to może być dobry czas na użycie 'typename' zamiast' class'? Ponieważ nie przekazujesz klas. Są funkcjonalnie równoważne, ale ważna jest ich czytelność. –

Powiązane problemy