Udostępnij za pośrednictwem


decltype — specyfikator typu

Specyfikator typu decltype wyrażenie daje pierwszeństwo podanemu typowi.Specyfikator typu decltype wraz z słowem kluczowym auto, jest przydatny głównie dla deweloperów, którzy piszą biblioteki szablonów.Należy używać auto i decltype do deklarowania funkcji szablonu, którego zwracany typ zależy od typów argumentów szablonu.Zamiast tego można użyć auto i decltype, aby zadeklarować funkcję szablonu, która otacza wywołanie do innej funkcji, a następnie zwraca typ taki, jaki zwraca funkcja opakowująca.

 decltype( expression )

Parametry

Parametr

Opis

expression

Wyrażenie.Aby uzyskać więcej informacji, zobacz Wyrażenia (C++).

Wartość zwracana

Typ parametru expression

Uwagi

Specyfikator typu decltype jest obsługiwany w Visual C++ 2010 lub w nowszej wersji i może być używany z kodu macierzystego lub zarządzanego.

Kompilator używa następujące reguły, aby określić typ parametru expression.

  • Jeśli parametr expression jest identyfikatorem lub dostępem do elementu członkowskiego klasy, decltype(expression) jest typem jednostki o nazwie expression.Jeśli nie ma żadnego takiego obiektu lub parametr expression nazywa zbiór przeciążonych funkcji, kompilator zwraca komunikat o błędzie.

  • Jeśli parametr expression jest wywołaniem funkcji lub funkcji przeciążonej operatora, decltype(expression) jest zwracanym typem funkcji.Nawiasy wokół przeciążonego operatora są ignorowane.

  • Jeśli parametr expression jest rvalue, decltype(expression) jest typem expression.Jeśli parametr expression jest lvalue, decltype(expression) jest odwołanie lvalue odnosi się do typu expression.

Poniższy przykład kodu pokazuje niektóre zastosowania specyfikatora typu decltype.Po pierwsze założono, że zostały zakodowane następujące instrukcje.

int var;
const int&& fx(); 
struct A { double x; }
const A* a = new A();

Następnie należy zbadać typy, które są zwracane przez cztery instrukcje decltype w poniższej tabeli.

Instrukcja

Typ

Uwagi

decltype(fx());

const int&&

Odwołanie rvalue do const int.

decltype(var);

int

Typ zmiennej var.

decltype(a->x);

double

Typ dostępu do elementu członkowskiego.

decltype((a->x));

const double&

Wewnętrzne nawiasy powodują, że instrukcja oceniana jest jako wyrażenie zamiast dostęp do elementu członkowskiego.A ponieważ a jest zadeklarowana jako wskaźnik const, typ jest to odwołanie do const double.

Decltype i Auto

Użyj specyfikatora typu decltype, wraz z słowem kluczowym auto do deklarowania funkcji szablonu, którego typ zwracany zależy od typów argumentów szablonu.Na przykład rozważmy poniższy przykład kodu, w którym zwracany typ funkcji szablonu zależy od typów argumenty szablonu.W przykładzie kodu symbol zastępczy UNKNOWN wskazuje, że nie można określić typu zwracanego.

template<typename T, typename U>
UNKNOWNfunc(T&& t, U&& u){ return t + u; }; 

Wprowadzenie specyfikatora typu decltype umożliwia developerowi uzyskać odpowiedni typ wyrażenia, które zwraca funkcja szablonu.Użyj alternatywna składnia deklaracji funkcji, która jest pokazana później, słowa kluczowego auto i specyfikatora typu decltype, aby zadeklarować zwracany typ późno określony.Późno określony typ zwracany jest określany po kompilacji deklaracji, a nie kiedy jest kodowany.

Następujący prototyp ilustruje składnię deklaracji funkcji alternatywnych.Należy zauważyć, że kwalifikatory const i volatile i throwspecyfikacja wyjątku są opcjonalne.Symbol zastępczy function_body reprezentuje instrukcję mieszanek, która określa, co robi funkcja.Jako najlepsze praktyki programowania, symbol zastępczy expression w instrukcji decltype powinien odpowiadać wyrażeniu określonemu przez instrukcję return, jeśli istnieje w function_body.

autofunction_name(parametersopc)constopcvolatileopc−>decltype(expression)throwopc{function_body};

W poniższym przykładzie kodu, późna deklaracja zwracanego typu funkcji szablonu myFunc jest określana przez typy argumentów szablonu t i u.Jako najlepsze praktyki kodowania, w przykładzie kodu użyto również referencji i funkcji szablonu forward, która obsługuje przekazywanie.Aby uzyskać więcej informacji, zobacz Deklarator odwołania do wartości R: &&.

template<typename T, typename U>
auto myFunc(T&& t, U&& u) -> decltype (forward<T>(t) + forward<U>(u)) 
        { return forward<T>(t) + forward<U>(u); }; 

Decltype i funkcja przesyłania dalej

Funkcja przesyłania dalej opakowuje wywołania innych funkcji.Należy wziąć pod uwagę szablon funkcji, który przekazuje jej argumenty lub wyniki wyrażenia, które obejmują te argumenty do innej funkcji.Ponadto funkcja przesyłania dalej zwraca wynik wywoływania innych funkcji.W tym scenariuszu zwracany typ funkcji przesyłania dalej powinien być taki sam, jak zwracany typ funkcji opakowującej.

W tym scenariuszu nie można napisać wyrażenia odpowiedniego typu bez specyfikatora typu decltype.Specyfikator typu decltype włącza funkcje generyczne przesyłania dalej, ponieważ nie traci wymaganych informacji na temat tego, czy funkcja zwraca typ odwołania.Aby uzyskać przykład kodu funkcji przesyłania dalej, zobacz poprzedni przykład funkcji szablonu myFunc.

Przykład

Poniższy przykład kodu deklaruje późno określony zwracany typ funkcji szablonu Plus().Funkcja Plus przetwarza jej operandy z przeciążeniem operator+.W związku z tym, interpretacja operatora plus (+) i zwracany typ funkcji Plus zależy od rodzaju argumentów funkcji.

// decltype_1.cpp
// compile with: /EHsc
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <utility>
#include <iomanip>

using namespace std;

template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) -> 
   decltype(forward<T1>(t1) + forward<T2>(t2))
{
   return forward<T1>(t1) + forward<T2>(t2);
}

class X
{
   friend X operator+(const X& x1, const X& x2)
   {
      return X(x1.m_data + x2.m_data);
   }

public:
   X(int data) : m_data(data) {}
   int Dump() const { return m_data;}
private:
   int m_data;
};

int main()
{
   // Integer 
   int i = 4;
   cout << 
      "Plus(i, 9) = " << 
      Plus(i, 9) << endl;

   // Floating point
   float dx = 4.0;
   float dy = 9.5;
   cout <<   
      setprecision(3) << 
      "Plus(dx, dy) = " <<
      Plus(dx, dy) << endl;

   // String      
   string hello = "Hello, ";
   string world = "world!";
   cout << Plus(hello, world) << endl;

   // Custom type
   X x1(20);
   X x2(22);
   X x3 = Plus(x1, x2);
   cout << 
      "x3.Dump() = " << 
      x3.Dump() << endl;
}

Dane wyjściowe

W tym przykładzie kodu pokazane są następujące wyniki.

13

13.5

Hello world.

42

Wymagania

Visual C++ 2010 lub nowsza wersja.

Zobacz też

Informacje

Pojedyncze nazwy typów