Satır içi anahtar kelimeyi şablonlarda kullanmak mantıklı mı?


119

Şablonlar başlıklar içinde tanımlandığı ve derleyici bir işlevi satır içine almanın avantajlı olup olmadığını belirleyebildiğinden, herhangi bir anlam ifade ediyor mu? Modern derleyicilerin bir işlevi ne zaman satır içi yapacaklarını daha iyi bildiklerini ve inlineipucunu görmezden geldiklerini duydum .


edit: Her iki cevabı da kabul etmek istiyorum, ancak bu mümkün değil. Sorunu kapatmak için phresnel'in cevabını kabul ediyorum , çünkü en çok oyu aldı ve resmi olarak haklı, ancak yorumlarda belirttiğim gibi Puppy 's and Component 10'u değerlendiriyorum. farklı bakış açısından, çok doğru olanlar kadar 'ın cevapları .

Sorun C ++ semantiğindedir ve inlineanahtar kelime ve satır içi söz konusu olduğunda katı değildir . phresnel "yazma satır içi bunu demek eğer" diyor, ama aslında ne anlama geldiğini inlineo kadar "ODR ihlalleri hakkında dırdır derleyiciler durur" bir direktif özgün anlamı evrimleştiği olarak belli değil Yavru diyor.

Yanıtlar:


96

Alakasız değil. Ve hayır, her işlev şablonu inlinevarsayılan olarak değildir. Standart, Açık uzmanlaşmada bile açıkça belirtilmiştir ([temp.expl.spec])

Aşağıdakilere sahip olun:

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

tpl.h (Açık Uzmanlık alanından alınmıştır):

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

Bunu derleyin ve işte:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

Belirten Değil inlineaçık örnekleme yapıyor da sorunlarına yol açabilir zaman.

Yani özetle : Tamamen özelleştirilmiş olmayan işlev şablonları için, yani en az bir bilinmeyen türü taşıyan şablonlar için, inlinehataları atlayabilir ve almayabilirsiniz , ancak yine de değildir inline. Tam uzmanlık alanları için, yani yalnızca bilinen türleri kullanan uzmanlar için, onu ihmal edemezsiniz.

Önerilen pratik kural : inlineEğer ciddiysen yazın ve tutarlı olun. Sırf yapabildiğin için yapıp yapmamak hakkında daha az düşünmeni sağlar. (Bu temel kural, Vandevoorde'un / Josuttis'in C ++ Şablonu: Tam Kılavuz ile uyumludur ).


2
Doğru yazılabilirdi. Ancak bu, öyle görünse bile, temelsizlik anlamına gelmez. Vandevoorde ve Josuttis ayrıca C ++ Şablonlarında
Sebastian Mach

43
Açık uzmanlık bir şablon değildir.
Puppy

2
@DeadMG: Yine de, aramada tam bir uzmanlık yerine normal bir işlev tercih edilir, bu nedenle bunlar şablon veya şablon değillerse, o zaman bunlar nedir?
Sebastian Mach

13
Bu cevap yanlış. Bir şablonun açık bir uzmanlığı, bir şablon değil, bir işlevdir. Bu işlev, inlineyalnızca özelleşmiş şablon ile işaretlendiği için olmaz inline. Yani inlineşablonda tamamen alakasız. Bu işlevin olması gerekip inlinegerekmediğinin, bir şablon uzmanlığı aracılığıyla üretilmesiyle hiçbir ilgisi yoktur (ve ne zaman kullanılacağını belirleyen bundan daha iyi yanıtlar vardır inline). @Puppy'nin aşağıdaki cevabı doğru, bu doğru değil. inlineBir şablona eklemek alakasızdır ve clang-tidyaslında onu kaldıracaktır.
gnzlbg

6
Ayrıca, örnek yalnızca normal işlevler için ODR sorunlarını gösterir (bu davranışın şablonlarla ilgisi yoktur). Bunun inlinealakasız olmadığını göstermeye çalışmak için örnek , anahtar kelime template<> void f<>(int) {} olmadan açıkça uzmanlaşma durumunu kapsamalıdır inline. Ancak o zaman bile inlineşablondaki belirticinin değiştirilmesi herhangi bir fark yaratmaz, çünkü şablonu işaretleyip işaretlememeniz önemli inlinedeğildir.
gnzlbg

34

Alakasız. Tüm şablonlar halihazırda mevcut inline- 2012 itibariyle inlineanahtar kelimenin tek kullanımının derleyicilerin ODR ihlallerinden şikayet etmesini durdurmak olduğunu belirtmiyorum bile . Kesinlikle haklısınız - mevcut nesil derleyiciniz kendi başına neyi satır içi yapacağını bilecek ve muhtemelen bunu çeviri birimleri arasında bile yapabilir.


11
Standart, tüm şablonların satır içi olduğunu belirtmez.
Sebastian Mach

16
@phresnel: Ancak şablonlar inline-işaretli işlevlerle aynı anlamlara sahiptir (yani, bağlayıcıya birden çok eşdeğer tanım geçirilebilir, bu da birini seçer). Satır içi değil, inlineanahtar kelimenin gerçek işlevi budur .
Ben Voigt

2
@BenVoigt: ODR'nin anlamını biliyorum inline. Belki aşağıdaki cevabıma (veya seçilen sıralamaya bağlı olarak yukarıdan) bir göz atabilirsiniz. Uzmanlaşmamış şablonlar için elbette haklısınız, ancak resmi olarak aynı değil.
Sebastian Mach

3
@DeadMG: C ++ 'da bir işlev şablonunun bir başlık dosyasında uygulanması gerekliliği yoktur; her yerde uygulanabilir. Bunu yansıtmak inlineiçin, satır içi olması gerekenleri etiketlemeyi öneriyorum . Genellikle hiçbir fark yaratmaz, ancak standart dilinde, aynı değildirler ve hepsi satır içi değildir. "İlgisiz" diyerek bu konudaki duruşunuzu kabul ediyorum, ancak standartlara göre, tüm şablonlar satır içi değildir, yalnızca sizin için bir C ++ olarak görünürler - kullanıcı gibi görünürler.
Sebastian Mach

7
Açık uzmanlaşmanın bir şablon olmadığı şeklindeki kabul edilen yanıta ilişkin yorumunuz (tabii ki öyle söylendikten sonra açıktır ) belki de bu sayfadaki en yararlı şeydir. Bunu cevabına da ekleyebilir misin?
Kyle Strand

6

Önerdiğiniz gibi, inlinederleyiciye bir ipucu ve daha fazlası değil. Bunu yok saymayı veya hatta satır içi olarak işaretlenmemiş satır içi işlevleri kullanmayı seçebilir.

inlineŞablonlarla birlikte kullanmak , eskiden her derleme biriminin aynı şablonlu sınıf için ayrı bir nesne oluşturması ve bu da bağlantı zamanında çoğaltma sorunlarına neden olması sorununu aşmanın (zayıf) bir yoluydu. inline(Sanırım) kullanarak , adın karıştırılması farklı sonuç veriyor, bu da bağlantı zamanında ad çatışmasını tamamlıyor, ancak büyük ölçüde şişirilmiş kod pahasına.  

Marshall Cline bunu burada benden daha iyi açıklıyor .


@Xeo: Durum böyle değildi. Şunu kontrol edin: gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/… Bunun yakın zamanda değiştiğini varsayıyorum, bu yüzden geçmiş zamanda konuşuyordum.
Bileşen 10

2
@Xeo: Bana Standardın işlev şablonlarının her zaman satır içi olduğunu belirten kısmına işaret edebilir misiniz? Çünkü değiller.
Sebastian Mach

@phresnel: İlginç, yemin edebilirim bunu standartta okudum. Belki bunu işlev şablonlarının ODR ( §14.5.5.1 p7 & p8) ' den muaf olduğu gerçeğiyle karıştırdım . Benim hatam, yanlış yorumu kaldırdım.
Xeo

@Component 10 Neden yuvarlak derleme sorunu almanın kötü bir yolu olduğunu düşünüyorsunuz
Kapil
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.