Genel kodda dönüş türü yönlendirme
Verdiğiniz ilk örnek gibi genel olmayan bir kod için, bir dönüş türü olarak referans almayı manuel olarak seçebilirsiniz:
auto const& Example(int const& i)
{
return i;
}
ama genel kod yapabileceksiniz istiyorum mükemmel bir dönüş türü iletmek Eğer bir başvuru veya bir değerle ilgili olup olmadığını bilmeden. decltype(auto)
size şu yeteneği verir:
template<class Fun, class... Args>
decltype(auto) Example(Fun fun, Args&&... args)
{
return fun(std::forward<Args>(args)...);
}
Özyinelemeli şablonlarda dönüş türü kesintisini geciktirme
Gelen bu Q & A şablonunun döndürme türü olarak belirtildi zaman bir kaç gün önce, şablon işlem yaptığı sonsuz yineleme karşılaşıldı decltype(iter(Int<i-1>{}))
yerine decltype(auto)
.
template<int i>
struct Int {};
constexpr auto iter(Int<0>) -> Int<0>;
template<int i>
constexpr auto iter(Int<i>) -> decltype(auto)
{ return iter(Int<i-1>{}); }
int main() { decltype(iter(Int<10>{})) a; }
decltype(auto)
burada şablon örnekleme tozu yerleştikten sonra dönüş türü kesintisini geciktirmek için kullanılır .
Diğer kullanımlar
decltype(auto)
Diğer bağlamlarda da kullanabilirsiniz , örneğin N3936 Standardı taslağında ayrıca
7.1.6.4 otomatik spesifikasyon [dcl.spec.auto]
1 auto
ve decltype(auto)
tür belirticileri, daha sonra değiştirilecek bir yer tutucu türünü, bir başlatıcıdan çıkarılmasıyla veya izleyen dönüş türüyle birlikte açık bir belirtmeyle belirtir. auto
Tip-spesifik fi er de lambda jenerik lamda olduğunu belirtmek için kullanılır.
2 Yer tutucu türü , decl-specifier-seq, type-specifier-seq, dönüşüm-işlev-kimliği veya izleyen-dönüş-tipinde bir işlev bildiricisiyle, böyle bir bildiricinin geçerli olduğu herhangi bir bağlamda görünebilir . İşlev bildiriminde, işlevin bildirilen dönüş türünü belirten bir izleyen dönüş türü (8.3.5) varsa. İşlevin bildirilen dönüş türü bir yer tutucu türü içeriyorsa, işlevin dönüş türü, varsa, işlev gövdesindeki döndürme ifadelerinden çıkarılır.
Taslak ayrıca bu değişken başlatma örneğini de içerir:
int i;
int&& f();
auto x3a = i; // decltype(x3a) is int
decltype(auto) x3d = i; // decltype(x3d) is int
auto x4a = (i); // decltype(x4a) is int
decltype(auto) x4d = (i); // decltype(x4d) is int&
auto x5a = f(); // decltype(x5a) is int
decltype(auto) x5d = f(); // decltype(x5d) is int&&
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i; // decltype(x7a) is int*
decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)