C ++ otomatik anahtar kelimesi. Neden sihir?


145

C ++ öğrenmek için kullandığım tüm malzemelerden, autoher zaman hiçbir amaca hizmet etmeyen garip bir depolama süresi belirleyicisi olmuştur. Ama son zamanlarda, kendi başına bir tür adı olarak kullanılan kodla karşılaştım. Merakın dışında denedim ve ne olursa olsun ona ne tür bir şey verdiğimi varsayar!

Aniden STL yineleyicileri ve şablon kullanan her şeyin yazılması 10 kat daha kolaydır. Python gibi 'eğlenceli' bir dil kullanıyormuşum gibi geliyor.

Bu anahtar kelime tüm hayatım boyunca neredeydi? Görsel stüdyoya özel ya da taşınabilir olmadığını söyleyerek hayallerimi keser misin?


18
değil. büyü. Yeni ( oh noes, ne kötü bir kelime oyunu ). Şimdi asenk gelecek ( nefes nefese )
sehe

2
İşte otomatik anahtar kelimelerle ilgili referans en.cppreference.com/w/cpp/language/auto
andyqee

Yanıtlar:


149

auto C ++ 'ın neredeyse sonsuza dek orada olan, ancak neredeyse hiç kullanılmadığı için C'den "miras aldığı" bir anahtar kelimeydi: ya izin verilmiyordu, ya da varsayılan olarak varsayılmıştı.

Kullanımı autoçıkarılmış bir türü anlamında C ++ 11 ile yeniydi.

Aynı zamanda, işlev şablonları için şablon türü kesinti çalışmalarıyla aynı türden auto x = initializertürünü çıkarır . Bunun gibi bir işlev şablonu düşünün:xinitializer

template<class T>
int whatever(T t) { 
    // point A
};

A noktasında T, parametre için iletilen değere göre bir tür atandı whatever. Bunu yaptığınızda auto x = initializer;, onu başlatmak için kullanılan xtürden türü belirlemek için aynı tür kesinti kullanılır initializer.

Bu, bir derleyicinin uygulaması gereken tür kesinti mekaniğinin çoğu anlamına gelir auto çoğunun zaten mevcut olduğu ve herhangi bir derleyici üzerindeki şablonlar için C ++ 98 / 03'ü uygulamaya çalışan bir tür girişimde bulunulduğu anlamına gelir. Bu nedenle, destek eklemek, autotüm derleyici takımları için oldukça kolaydı - oldukça hızlı bir şekilde eklendi ve bununla ilgili birkaç hata var gibi görünüyor.

Bu cevap başlangıçta yazıldığında (2011'de, mürekkep C ++ 11 standardında kuru olmadan önce) autozaten oldukça taşınabilirdi. Günümüzde, tüm ana derleyiciler arasında tamamen taşınabilir. Bundan kaçınmanın tek bariz nedeni, bir C derleyicisiyle uyumlu kod yazmanız gerektiğinde veya desteklemediğini bildiğiniz bazı niş derleyicileri hedeflemek için özel bir gereksiniminiz varsa (örneğin, birkaç kişi hala kod yazıyorsa) MS-DOS için onlarca yıldır önemli yükseltmeler görmemiş olan Borland, Watcom, vb. derleyicileri kullanarak). Ana derleyicilerin herhangi birisinin makul bir sürümünü kullanıyorsanız, bundan kaçınmak için hiçbir neden yoktur.


24

Sadece işe yaramaz bir anahtar kelime alıyor ve yeni, daha iyi bir işlevsellik sağlıyor. C ++ 11'de standarttır ve bazı C ++ 11 desteğine sahip çoğu C ++ derleyicisi bunu destekleyecektir.


Ah! Aha, C ++ dilini asla kendi içinde değişebilecek bir şey olarak düşünmemişti. Bu C ++ 11'de başka neler eklediklerine bakmak zorunda kalacağım, biraz C ++ 0x duydum ama asla çok derin kazmadım.
Anne Quinn

7
@Clairvoire C ++ 0x geçici addı. Bu ay yayınlandı ve böylece C ++ 11 oldu.
R. Martinho Fernandes

13

Değişkenler için, bildirilen değişkenin türünün başlatıcıdan otomatik olarak düşüleceğini belirtir. İşlevler için, dönüş türünün sondaki dönüş türü olduğunu veya dönüş ifadelerinden düşüleceğini belirtir (C ++ 14'ten beri).

Sözdizimi

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

açıklama

1) Değişkenleri blok kapsamında, ad alanı kapsamında, döngüler için başlatma deyimlerinde vb. Bildirirken, auto anahtar sözcüğü tür belirleyicisi olarak kullanılabilir. Başlatıcı türü belirlendikten sonra, derleyici, bir işlev çağrısından şablon bağımsız değişkeni kesinti kurallarını kullanarak otomatik anahtar kelimeyi değiştirecek türü belirler (ayrıntılar için şablon bağımsız değişken kesinti # Diğer bağlamlara bakın). Auto anahtar sözcüğüne, tür indirimine katılacak const veya & gibi değiştiriciler eşlik edebilir. Örneğin, const auto& i = expr;i template<class U> void f(const U& u)fonksiyonu, eğer işlev çağrısı yaparsa , tam olarak hayali bir şablondaki u argümanının türüdür.f(expr)derlendi. Bu nedenle, otomatik &&, döngü için aralık tabanlı olarak kullanılan başlatıcıya göre bir lvalue referansı veya rvalue referansı olarak çıkarılabilir. Birden fazla değişkeni bildirmek için otomatik kullanılırsa, çıkarılan türlerin eşleşmesi gerekir. Örneğin auto i = 0, d = 0.0;, deklarasyon auto i = 0, *p = &i;iyi biçimlenmemişken, deklarasyon iyi biçimlendirilmiş ve otomatik int olarak çıkarılmıştır.

2) Sondaki dönüş türü sözdizimini kullanan bir işlev bildiriminde, auto anahtar sözcüğü otomatik tür algılama gerçekleştirmez. Yalnızca sözdiziminin bir parçası olarak hizmet eder.

3) Sondaki dönüş türü sözdizimini kullanmayan bir işlev bildiriminde, auto anahtar sözcüğü, dönüş türünün, şablon bağımsız değişkeni kesinti kuralları kullanılarak dönüş ifadesinin işlenenden düşüleceğini belirtir.

4) Değişkenin bildirilen türü decltype (auto) ise, auto anahtar sözcüğü, başlatıcısının ifadesi (veya ifade listesi) ile değiştirilir ve gerçek tür, decltype kuralları kullanılarak çıkarılır.

5) İşlevin dönüş türü decltype (auto) olarak bildirilirse, auto anahtar sözcüğü, return ifadesinin işleneniyle değiştirilir ve gerçek dönüş türü, decltype kuralları kullanılarak çıkarılır.

6) auto :: formunun iç içe ad belirteci, kısıtlanmış tür yer tutucu kesinti kurallarına göre bir sınıf veya numaralandırma türüyle değiştirilen bir yer tutucudur.

7) Lambda ifadesinde parametre bildirimi. (C ++ 14'ten beri) Bir fonksiyon parametresi bildirimi. (TS kavramları)

Notlar C ++ 11'e kadar, auto bir depolama süresi belirleyicisinin semantiğine sahipti. Otomatik değişkenlerin ve işlevlerin, bir bildirimle olduğu gibi karıştırılmasına auto f() -> int, i = 0;izin verilmez.

Daha fazla bilgi için: http://en.cppreference.com/w/cpp/language/auto


11

Bu işlevsellik tüm yaşamınız boyunca orada değildi. 2010 sürümünden beri Visual Studio'da desteklenmektedir. Bu yeni bir C ++ 11 özelliğidir, bu nedenle Visual Studio'ya özel değildir ve taşınabilir / taşınabilir olacaktır. Çoğu derleyici bunu zaten destekliyor.


3

Hiçbir yere gitmiyor ... C ++ 11'in uygulanmasında yeni bir standart C ++ özelliği. Bununla birlikte, nesne çağrılarını basitleştirmek ve belirli çağrı paradigmaları için sözdizimini temizlemek için harika bir araç olsa da (yani, döngüler için aralık tabanlı), aşırı kullanmayın / kötüye kullanmayın :-)


3

Auto anahtar sözcüğü, bildirilen değişkenin türünün başlatıcıdan otomatik olarak düşüleceğini belirtir. İşlevler durumunda, dönüş türleri otomatikse, çalışma zamanında dönüş türü ifadesiyle değerlendirilir.

Yineleyiciyi kullanmamız gerektiğinde çok yararlı olabilir. Örneğin, aşağıdaki kod için, tüm yineleyici sözdizimini yazmak yerine "otomatik" i kullanabiliriz.

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

"Auto" anahtar kelimesini bu şekilde kullanabiliriz


0

Magic, belirli işlevlere geçirilen her Değişken Türü için kod yazma zorunluluğunu azaltmasıdır. C tabanındaki Python benzeri bir print () işlevini düşünün.

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.