Şablon varsayılan bağımsız değişkenleri


158

Aşağıdakileri yapmama izin verilirse:

template <typename T = int>
class Foo{
};

Neden esas olarak aşağıdakileri yapmama izin verilmiyor?

Foo me;

Ancak şunu belirtmeliyim:

Foo<int> me;

C ++ 11 varsayılan şablon argümanlarını tanıttı ve şu anda tam anlamam için anlaşılması zor.

Yanıtlar:


197

Yapmak zorundasın:

Foo<> me;

Şablon bağımsız değişkenleri mevcut olmalıdır, ancak bunları boş bırakabilirsiniz.

Bunu foo, tek bir varsayılan argümana sahip bir işlev olarak düşünün . İfade fooonu çağırmayacak, ama foo()arayacak. Bağımsız değişken sözdizimi hala orada olmalıdır. Bu, bununla tutarlı.


4
Ben eğer bazı gereksiz komplikasyonlar yaratacak varsayalım @Pubby Foo olabilir şablon tanımlayıcı veya olabilecek varsayılan bir argüman var olmasına bağlı olarak açık bir örnekleme olabilir. Açık örnekleme sözdizimini daha iyi koruyun. Bunu footek bir varsayılan parametreye sahip bir işlev olarak düşünün . Gibi arayamazsın foo, onunla arayacaksın foo(). Bunu tutarlı tutmak mantıklı.
Joseph Mansfield

2
@sftrabbit ancak hiçbir argüman olmadan bir işlevi çağıramazsınız foo; Fooancak argümansız bir sınıfı adlandırabilirsiniz .
Seth Carnegie

4
@aschepler Bir fonksiyonla, şablon argümanları fonksiyon argümanlarından çıkarılabilir. Bir sınıfla, varsayılan bağımsız değişkenlere sahip bir şablon sınıfını mı yoksa şablon olmayan bir sınıfı mı kastettiğinizi karar vermek mümkün değildir.
Olaf Dietsche

21
@OlafDietsche, ancak aynı ada sahip bir şablon sınıfınız ve şablon olmayan bir sınıfınız olamaz, bu nedenle derleyici yalnızca adın ne olduğuna bakarak karar verebilmelidir.
Seth Carnegie

7
@Pubby Standart komite, sanırım kendilerine aynı şeyi sordu. Şimdi, C ++ 17 <>ile bu durumda artık gerekli değildir. Daha fazla ayrıntı için cevabıma bakın.
Paolo M

63

C ++ 17 ile gerçekten yapabilirsiniz.

Bu özelliğe sınıf şablonu bağımsız değişken kesintisi adı verilir ve şablonlu türlerin değişkenlerini bildirme biçiminize daha fazla esneklik kazandırır .

Yani,

template <typename T = int>
class Foo{};

int main() {
    Foo f;
}

artık yasal C ++ kodudur .


5
Garip. Sadece C ++ 17 projemde denedim ve işe yaramadı: "şablon yer tutucu türü 'const MyType'ın ardından basit bir tanımlayıcı kimliği gelmeli". GCC 7.3.0 kullanıyorum.
Silicomancer

1
@Silicomancer Kodunuzu ve komut satırınızı görmeden söylemek zor ... Belki buradaki gibi işaretçilerle mi uğraşıyorsunuz ?
Paolo M

1
Clang göründüğünü kabul etmiyor mu? coliru.stacked-crooked.com/a/c5d3c0f90ed263c2
Borgleader

2
@PaoloM Oh harika, onun sadece bir derleyici sürümü sorunu olduğunu bildiğime sevindim. Bunu araştırdığınız için teşekkürler.
Borgleader

3
Bu en iyi cevap olmalıdır - en iyi cevap güncel değildir.
drew

20

Bunu yapmana izin yok ama bunu yapabilirsin

typedef Foo<> Fooo;

ve sonra yap

Fooo me;

bunda varsayılan bir tür ve: typedef Foo<float> Fooo;varsayılan tür olmadan herhangi bir fark var mı?
qrikko

7
C ++ 11 benzeri bir yol söylemek olabilirusing Fooo = Foo<>;
Adrian W

18

Aşağıdakileri kullanabilirsiniz:

Foo<> me;

Ve intşablon argümanınız olun. Köşeli parantezler gereklidir ve ihmal edilemez.


Mantıklı ve teşekkür ediyor, ancak aşağıda belirtildiği gibi, belirtilen tür neden mevcut değil?
user633658

@ user633658: "Tür belirleyici" mi demek istediniz? Anladığımdan emin değilim
Andy Prowl

Her neyse, boş köşeli parantez ihtiyacının arkasındaki nedenle ilgili olarak, sadece varsayımlar yapabilirim ve bunların hepsi, yalnızca şablonun adının kullanımıyla olası belirsizlikleri ortadan kaldırmakla ilgilidir, ancak itiraf etmeliyim ki tam olarak sebep
Andy Prowl

<> Gereksiniminin, derleyicinin ayrıştırıcısının foo denen başka bir şeyden ziyade foo adlı şablonlu bir sınıfa başvurduğunuzu belirlemesini sağlamak olduğundan kesinlikle şüpheleniyorum.
Mac
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.