Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Specifikátor decltype typu poskytuje typ zadaného výrazu. Specifikátor decltype typu spolu s klíčovým slovemauto je užitečný především vývojářům, kteří píší knihovny šablon. Použijte auto a decltype deklarujte šablonu funkce, jejíž návratový typ závisí na typech argumentů šablony. Nebo můžete použít auto a decltype deklarovat šablonu funkce, která zabalí volání jiné funkce, a poté vrátí návratový typ zabalené funkce.
Syntaxe
decltype(expression)
Parametry
expression
Výraz. Další informace naleznete v tématu Výrazy.
Návratová hodnota
Typ parametru expression .
Poznámky
Specifikátor decltype typu je podporován v sadě Visual Studio 2010 nebo novějších verzích a lze ho použít s nativním nebo spravovaným kódem.
decltype(auto) (C++14) se podporuje v sadě Visual Studio 2015 a novějších verzích.
Kompilátor používá následující pravidla k určení typu parametru expression .
expressionPokud je parametr identifikátorem nebo přístupem člena třídy,decltype(expression)je typem entity pojmenované .expressionPokud neexistuje taková entita nebo název parametruexpressionmnožinu přetížených funkcí, kompilátor zobrazí chybovou zprávu.expressionPokud je parametr voláním funkce nebo přetíženou funkcí operátoru,decltype(expression)je návratovým typem funkce. Závorky kolem přetížené operátoru jsou ignorovány.expressionPokud je parametr rvalue,decltype(expression)je typexpression.expressionPokud je parametr lvalue,decltype(expression)je lvalue odkaz na typ .expression
Následující příklad kódu ukazuje některé použití specifikátoru decltype typu. Nejprve předpokládejme, že jste naprogramovali následující příkazy.
int var;
const int&& fx();
struct A { double x; };
const A* a = new A();
Dále prozkoumejte typy vrácené čtyřmi decltype příkazy v následující tabulce.
| Prohlášení | Typ | Poznámky |
|---|---|---|
decltype(fx()); |
const int&& |
Rvalue odkaz na .const int |
decltype(var); |
int |
Typ proměnné var. |
decltype(a->x); |
double |
Typ přístupu člena. |
decltype((a->x)); |
const double& |
Vnitřní závorky způsobí, že se příkaz vyhodnotí jako výraz místo přístupu člena. A protože a je deklarován jako const ukazatel, typ je odkaz na const double. |
decltype a auto
V jazyce C++14 můžete k deklaraci šablony funkce, jejíž návratový typ závisí na typech argumentů šablony, použít decltype(auto) bez koncového návratového typu.
V jazyce C++11 můžete pomocí specifikátoru decltype typu na koncovém návratovém typu společně s auto klíčovým slovem deklarovat šablonu funkce, jejíž návratový typ závisí na typech argumentů šablony. Představte si například následující příklad kódu, ve kterém návratový typ šablony funkce závisí na typech argumentů šablony. V příkladu kódu zástupný symbol označuje, UNKNOWN že návratový typ nelze zadat.
template<typename T, typename U>
UNKNOWN func(T&& t, U&& u){ return t + u; }
Zavedení specifikátoru decltype typu umožňuje vývojáři získat typ výrazu, který vrátí šablona funkce. Použijte alternativní syntaxi deklarace funkce , která se zobrazí později, auto klíčové slovo a decltype specifikátor typu k deklaraci opožděného návratového typu. Pozdní návratový typ je určen při kompilaci deklarace, nikoli při kódování.
Následující prototyp znázorňuje syntaxi alternativní deklarace funkce. Kvalifikátory const a volatilethrowspecifikace výjimky jsou volitelné. Zástupný function_body symbol představuje složený příkaz, který určuje, co funkce dělá. Osvědčeným postupem kódování by expression měl zástupný symbol v decltype příkazu odpovídat výrazu určenému příkazem return ( pokud existuje) v objektu function_body.
auto
function_name
(
parameters
volit)constvolitvolatilevolit->decltype(expression)noexceptvolit{function_body};
V následujícím příkladu kódu je pozdní návratový myFunc typ šablony funkce určen typy t argumentů šablony a u šablony. Osvědčeným postupem kódování je, že v příkladu kódu se také používají odkazy na hodnoty rvalue a forward šablona funkce, které podporují dokonalé přeposílání. Další informace naleznete v tématu Deklarátor odkazu Rvalue: &>.
//C++11
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); }
//C++14
template<typename T, typename U>
decltype(auto) myFunc(T&& t, U&& u)
{ return forward<T>(t) + forward<U>(u); }
decltype funkce předávání (C++11)
Přesměrování funkcí zabalí volání do jiných funkcí. Představte si šablonu funkce, která předá argumenty, nebo výsledky výrazu, který tyto argumenty zahrnuje, na jinou funkci. Funkce přesměrování navíc vrátí výsledek volání druhé funkce. V tomto scénáři by návratový typ funkce předávání měl být stejný jako návratový typ zabalené funkce.
V tomto scénáři nemůžete napsat odpovídající výraz typu bez specifikátoru decltype typu. Specifikátor decltype typu umožňuje obecné funkce předávání, protože neztratí požadované informace o tom, jestli funkce vrací odkazový typ. Příklad kódu funkce pro předávání najdete v předchozím myFunc příkladu šablony funkce.
Příklady
Následující příklad kódu deklaruje pozdní zadaný návratový typ šablony Plus()funkce . Funkce Plus zpracovává své dva operandy s přetížením operator+ . Interpretace operátoru plus (+) a návratového Plus typu funkce proto závisí na typech argumentů funkce.
// decltype_1.cpp
// compile with: cl /EHsc decltype_1.cpp
#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;
}
Plus(i, 9) = 13
Plus(dx, dy) = 13.5
Hello, world!
x3.Dump() = 42
Visual Studio 2017 a novější: Kompilátor analyzuje argumenty decltype , když jsou šablony deklarovány místo vytvoření instance. Takže pokud se v argumentu decltype najde nespolézená specializace, neodloží se na vytvoření instance, zpracuje se okamžitě a všechny výsledné chyby se v té době diagnostikují.
Následující příklad ukazuje takovou chybu kompilátoru, která je vyvolána v okamžiku deklarace:
#include <utility>
template <class T, class ReturnT, class... ArgsT> class IsCallable
{
public:
struct BadType {};
template <class U>
static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int); //C2064. Should be declval<U>
template <class U>
static BadType Test(...);
static constexpr bool value = std::is_convertible<decltype(Test<T>(0)), ReturnT>::value;
};
constexpr bool test1 = IsCallable<int(), int>::value;
static_assert(test1, "PASS1");
constexpr bool test2 = !IsCallable<int*, int>::value;
static_assert(test2, "PASS2");
Požadavky
Visual Studio 2010 nebo novější verze
decltype(auto) vyžaduje Visual Studio 2015 nebo novější.