2017-06-26 45 views
6

std::is_function specjalizuje się dla typów, które mają sygnaturę podobnego do:Co to jest int (int) i lub int (int) const i?

int(int) & 

zobaczyć tutaj: std::is_function

Ale to nie wskaźnik do metody użytkownik, który podpis może być:

int(T::*)(int) & 

Nie może to być także odniesienie do funkcji:

int (&)(int) 

Czym więc jest ten dziwny podpis?

Odpowiedz

13

Jest to typ funkcji, który istnieje tylko w systemie typów. Nie można go nigdy stworzyć.

Ale to nie wskaźnik do metody użytkownik, który może być podpis:

int(T::*)(int) & 

Jest to, bez wskaźnika. System typów pozwala opisać to jako typ.

#include <type_traits> 

struct T { }; 
using A = int(int) &; 
using B = A T::*; 
using C = int(T::*)(int) &; 

static_assert(std::is_same_v<B, C>); 

@ T.C. wymienia PR0172R0, która omawia, w jaki sposób obecność tych typów powoduje problemy dla autorów bibliotek i sugeruje kilka opcji, które mogą zmniejszyć te problemy. Jedną z opcji jest całkowite pozbycie się ich, inne zmniejszenie ich wpływu. W zależności od tego, jak to się stanie, ta odpowiedź może być poprawna w przyszłych wersjach C++.

+3

Chciałbym zamieścić link do ładnego podsumowania w [P0172R0] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html). –

+0

@ T.C. Dzięki, dodał wzmiankę. – hvd

+3

Wierzę, że można również "przy użyciu A = int (int) &; struct Bob {Foo; }; '. – Yakk

6

Na stronie dokumentacji Ci link do zobaczysz ten komentarz:

// specialization for function types that have ref-qualifiers 

powyższej listy przykładów można odwołać pochodzą.

Są to funkcje z kwalifikacjami referencyjnymi, o których można przeczytać więcej na temat here.

Podsumowując, są one podobne do funkcji kwalifikowanych const. Oto przykład:

struct foo 
{ 
    void bar() & { std::cout << "this is an lvalue instance of foo" << "\n"; } 
    void bar() && { std::cout << "this is an rvalue instance of foo" << "\n"; } 
}; 

int main(int argc, char* argv[]) 
{ 
    foo f{}; 
    f.bar();   // prints "this is an lvalue instance of foo" 
    std::move(f).bar(); // prints "this is an rvalue instance of foo" 

    return 0; 
} 

Nie mogę wymyślić wielkiego przypadku użycia tej funkcji, ale można jej użyć.

+1

[tutaj] (https://github.com/dropbox/nn/blob/master/nn.hpp#L83) to przykład użycia;) –

5

Od początku czasów (odnosząc się do pierwszego C standardzie ++) można zadeklarować takie „dziwne” typy funkcyjne jak np

typedef int F() const; 

Pomimo faktu, że powyższa deklaracja natychmiast nie pociąga za sobą żadnych zajęć , w tym przypadku końcowy const może służyć tylko jako const-kwalifikacja niestatycznej funkcji składowej klasy. Ogranicza to użycie powyższej nazwy do deklaracji członków klasy. Na przykład, można go używać w następujący sposób

struct S { 
    F foo;    // Declares an `int S::foo() const` member function 
}; 

int S::foo() const { // Defines it 
    return 42; 
} 

F S::*p = &S::foo; // Declares 'p' as `int (S::*)() const` pointer 

zauważyć, że jednak niejasne, jest to „klasyczny” C++ funkcja, która już w języku przez długi czas.

To, co masz w swoim przykładzie, to faktycznie to samo, ale z C++ 11 ref-qualifier zamiast kwalifikatora const.