2013-04-07 25 views
8

arasındaki fark this question cevap aşağıdaki gcc ile kodunu (code compiled) ve clang (code rejected) çalıştı Ben Test::f constexpr başlatılması tamam olduğunu düşünüyorum rağmen. Hata clang çıkışları ise:statik constexpr işaretçi işleve, derleyici

error: non-type template argument for template parameter of pointer type 'func' 
     (aka 'long (*)(int)') must have its address taken 
  1. hangi derleyici doğru?
  2. Clang doğruysa, neden ve bu hata gerçekten ne anlama geliyor?

DÜZENLEME: "neden", DyP's question bakınız için.

:

+0

ben '& function' aslında' constexpr' için geçerli bir başlatıcı olup olmadığını merak ediyorum. Her iki derleyici de öyle görünüyor. Ama bana çok hoş geliyor. Bu derleme zamanında bilinmez, sadece bağlantı zamanında. – Omnifarious

+0

'& function' bir fonksiyonun adresidir, bu yüzden benim için derleme zamanında bilinir ... Örneğin, bir imleci şablon argümanı olarak işlev görecek şekilde iletebilirsiniz. – Synxis

+1

Bir işlevin bir göstergesi, bir şey… eğer bu paylaşılan bir kütüphanenin bir parçasıysa, örneğin, adres muhtemelen bir "constexpr" olarak nitelendirilebilir mi? –

cevap

8

14.3.2 şablonu olmayan tür bağımsız değişkenleri [temp.arg.nontype]

olmayan bir türü için bir şablon bağımsız değişken olmayan şablon, şablon parametreli biri olacaktır [...]

- sabit bir ifade (5.19) statik depolama> süresi ve dış veya iç bağlantı veya işlev şablonları ve fonksiyon şablon kapsayan dış ya da iç bağlantı sahip bir fonksiyonu olan bir nesnenin adresine koyduğunu -dekiler hariç & kimlik tanımlaması olarak ifade edilen (parantezleri göz ardı ederek) & kimlik ifadesi, & adı, bir işlev veya diziye başvuruyorsa ve karşılık gelen şablon parametresi bir başvuru olduğunda göz ardı edilmesi dışında, statik olmayan sınıf üyelerine belirtilmiş; [...]

(n3485, vurgu benim) Ben sınırlı tam olarak neden bilmiyorum ama fonksiyon adresi mevcut değildir aslında ilişkili olabileceğini düşünüyorum

derleme zamanı (şablon örnekleme amaçlarının yerini alabilir).


Düzenleme: nedeniyle Synxis

bir izlem soruya (yorum)
constexpr func = &function; 

^bu iyi biçimliyken için Geliştirilmiş cevabı; Bir constexpr nesnesini başlatmak için bir işlevin adresini kullanabilirsiniz. sorun açıkça forma &identifier ait dışındaki olmayan tip şablon argümanları olarak işaretçileri kullanmak yasak olmasıdır:

using My_Call  = Call < &function >; // fine 

constexpr func mypointer = &function; // fine 
using My_Ind_Call = Call <func>;  // forbidden, argument not of form `&id` 
+3

Bu bir gözetim gibi görünüyor. Bir "constexpr" öğesine bir "constexpr" öğesi atarsanız ve bunu başka bir "constexpr" öğesine atarsanız, geçişli olmalıdır. – Omnifarious

+3

@Omnifarious It ** bir ** constexpr'dir. Ancak, şablon olmayan bir argüman olarak açıkça yasaklanmıştır. – dyp

+0

Eh, bu ilginç. Açıkça ortogonal olarak tedavi edilmez. Akıl yürütmenin ne olduğunu merak ediyorum. Yine de güçlü bir şüphem var. Benim tahminim, linker tarafından yeniden yerleştirilebilecek nesnelerin şablonlar için manevra kurallarında isimle anılmasıdır. Derleyicilerin bu tür "constexpr" gibi orijinal isimlerini taşımasını zorunlu kılmak, bazı senaryolarda oldukça zor ve muhtemelen imkansızdır. – Omnifarious

İlgili konular