2014-10-17 19 views
5

natknąłem się na następujący kod:Co oznacza typ "char (& (...)) [2]"?

char (&f(...))[2];

sprawdziłem typ nim (za pomocą typeid i C++ FiLt) i otrzymała:

char (&(...)) [2]

Ale nie mogę sensu tego typu. [2] to część, która mnie wyrzuca. Bez, może replikować się w definicji rodzaju funkcji, np

char (&f(...))

f jest tego samego typu co godzinę w (przynajmniej z wyjścia typeid i C++ filt)

char& h(...)

+0

Proszę zaksięgować pełny kontekst, w którym pojawia się ten kod. –

+0

nie jest to odwołanie do tablicy 2 funkcji zwracających char i przyjmujących elipse w stylu C? – Creris

+3

Jest to funkcja zwracająca odwołanie do tablicy dwóch znaków. Drugi ('char (& f (...))') jest funkcją zwracającą odwołanie do znaku. W drugim przypadku nawias zewnętrzny jest zbędny, aw obu przypadkach "..." jest pakietem argumentów variadycznych. – 0x499602D2

Odpowiedz

3

jest to funkcja, która deklaracja zmiennej liczby parametrów i zwraca odwołanie do tablicy znaków dwóch elementów.

Można ją oznaczyć jako prostszą przy użyciu polecenia typedef. Na przykład

typedef char char_array[2]; 

char_array & f(...); 
2

Można użyć cdecl i zastąpić dowolny typ dla elipsy, takich jak int:

char (&f(int)) [2] 

prowadzi do

zadeklarować f jako funkcji (int) powracającego odniesienia do tablicy 2 z char [...]

Zastąpić z powrotem i masz deklarację w słowach.

2
char (&f(...))[2]; 

Jest to deklaracja funkcji zwracającej odwołanie do tablicy złożonej z dwóch znaków. Nawiasy są potrzebne, aby były poprawne pod względem składniowym. W przeciwnym razie & będzie wiązać się z char i wystąpi błąd składniowy, ponieważ [2] jest bez znaczenia.

Składnię można rozłożyć za pomocą aliasu typu. Np

using array_ref = char (&)[2]; 
array_ref f(...); 

Powodem dla powrotu odniesienie do tablicy, a nie rzeczywistym macierzy Wynika to z faktu, że matryce nie mogą być zwrócone z funkcji. To niemożliwe. Możesz tylko zwracać referencje lub wskaźniki do tablic, tak jak funkcje.

We wszystkich przykładach ... to C variadic argument pack.


Jedynymi miejscami, gdzie widziałem tego rodzaju składni, gdzie jest on używany jako część uchwały przeciążenia funkcji dla SFINAE. Zwykle ta funkcja towarzyszy przeciążeniu tej samej nazwy, która używa substytucji szablonu do sprawdzania atrybutu danego typu.Jeśli wystąpi awaria substytucji, drugie przeciw-przeciążenie (to, które przyjmuje pakiet variadic) zostanie wybrane jako awaryjne. Jego typ zwrotu różnicuje sukces lub porażkę.

Na przykład, oto klasa cecha, która sprawdza, czy typ posiada funkcję składową f():

template <typename T> 
struct has_f 
{ 
private: 
    using true_type = char (&)[1]; 
    using false_type = char (&)[2]; 

    template <typename U> 
    static decltype(std::declval<U>().f(), true_type()) f(int); 

    template <typename> 
    static false_type f(...); 
public: 
    static constexpr bool value = sizeof(check<T>(0)) == 1; 
}; 

Jak widać, jeśli T posiada funkcję składową f(), wówczas wielkość zwrócony będzie 1, w przeciwnym razie 2. true_type i false_type są w dużej mierze zastąpione standardowymi klasami cech std::true_type i std::false_type tych dni, ale jest to po prostu przykład ilustrujący jego użycie.