2012-05-25 27 views
598

Wiem, że w C++ 11 możemy teraz używać using napisać typu alias, jak typedef s:Jaka jest różnica między "typedef" i "using" w C++ 11?

typedef int MyInt; 

Czy, z tego co rozumiem, co odpowiada:

using MyInt = int; 

i że nowa składnia wyłonił się z wysiłkiem mieć sposób, aby wyrazić „template typedef”:

template< class T > using MyType = AnotherType< T, MyAllocatorType >; 

Ale z pierwszymi dwoma non-t przykłady emplate, czy są jakieś inne subtelne różnice w standardzie? Na przykład: typedef s aliasing w "słaby" sposób. To znaczy, że nie tworzy nowego typu, ale tylko nową nazwę (konwersje są niejawne między tymi nazwami).

Czy to samo jest z using lub czy generuje nowy typ? Czy są jakieś różnice?

+145

ja osobiście wolę nową składnię, ponieważ jest znacznie bardziej podobny do zwykłego przypisania zmiennej, poprawy czytelności. Na przykład wolisz 'typedef void (& MyFunc) (int, int);' lub 'using MyFunc = void (int, int);'? –

+3

W pełni się zgadzam, teraz używam tylko nowej składni. Dlatego pytałem, aby mieć pewność, że naprawdę nie ma różnicy. – Klaim

+56

@ MatthieuM. te dwa są różne przy okazji. Powinien to być 'typedef void MyFunc (int, int);' (który tak naprawdę nie wygląda tak źle) lub 'using MyFunc = void (&) (int, int);' –

Odpowiedz

401

są równoważne ze standardowego (kopalni nacisk), (7.1.3.2)

typedef nazwa może być również wprowadzona przez ps-zgłoszeniu. Identyfikator następujący po słowie kluczowym using staje się nazwą typefunkcyjną i opcjonalnym parametrem-specyfikatorem-atrybutu po identyfikatorze o nazwie dla tej nazwy typedef. Ma tę samą semantykę, jakby była wprowadzona przez specyfikator typedef. W szczególności, nie definiuje nowego typu i nie pojawia się w identyfikatorze typu.

+14

Z odpowiedzi słowo kluczowe 'using' wydaje się być nadzbiorem' typedef'. Czy w przyszłości 'typdef' będzie przestarzały? – iammilind

+0

To wyjaśnia. – Klaim

+4

@iammilind prawdopodobnie nie, ale możesz kodować tak, jakby był. – bames53

139

Składnia przy użyciu ma tę zaletę, że jest używana w szablonach. Jeśli potrzebujesz abstrakcji typu, ale także musisz zachować parametr szablonu, aby możliwe było określenie w przyszłości. Powinieneś napisać coś takiego.

template <typename T> struct whatever {}; 

template <typename T> struct rebind 
{ 
    typedef whatever<T> type; // to make it possible to substitue the whatever in future. 
}; 

rebind<int>::type variable; 

template <typename U> struct bar { typename rebind<U>::type _var_member; } 

Ale użyciu składni upraszcza ten przypadek użycia.

template <typename T> using my_type = whatever<T>; 

my_type<int> variable; 
template <typename U> struct baz { my_type<U> _var_member; } 
+20

Już wskazałem to w pytaniu. Moje pytanie dotyczy tego, czy nie używasz szablonu, czy jest jakaś różnica w stosunku do typedef. Na przykład, gdy używasz "Foo foo {init_value};" zamiast "Foo foo (init_value)" obie mają robić to samo, ale nie wypełniają dokładnie tych samych reguł. Więc zastanawiałem się, czy istnieje podobna ukryta różnica z użyciem/typedef. – Klaim

101

Są one w dużej mierze takie same, z wyjątkiem tego

The alias declaration is compatible with templates, whereas the C style typedef is not.

+12

Szczególnie lubi prostotę odpowiedzi i wskazuje pochodzenie składu. – g24l

Powiązane problemy