2014-12-30 15 views
7

Hem 5.0 ve çınlama 3.6 aşağıdaki örnekte typename anahtar kelime gerektirir gcc:Bir atma veya silme ifadesi hiç bağımlı olabilir mi?

template<typename T> 
struct B 
{ 
    typedef int Type; 
}; 

template<int n> 
struct A 
{ 
    typedef typename B<decltype(throw (int*)n)>::Type Throw; 
    typedef typename B<decltype(delete (int*)n)>::Type Delete; 
}; 

Bu, C++ 11 standardında, aşağıdaki ifadeler ile kaplanmıştır:

[hariç]/2

Atama ifadesi, void türüdür.

[expr.delete]/1

işlenen türü nesne için bir işaretçi veya türü nesne için bir işaretçi olmayan tek bir açık dönüşüm fonksiyonu olan bir sınıf tipi olacaktır. Sonuçta void var.

Bu nedenle, her iki durumda da ürününün void ürettiğini varsayıyorum. bu, potansiyel olarak değerlendirildi alt ifade

  • yeni ifade olarak aşağıdakilerden biri içermediği sürece

    [expr.const]/2

    bir koşullu ifade çekirdek sabit ifadesidir

  • bir atış ifade

Bu, throw veya delete'u içeren bir ifadenin, sabit bir ifade olamayacağını belirtir. Bu,Bu

  • şablon adı bir şablon parametresi olan veya daha basit bir şablon kimliği ise

    [temp.dep.type]/8

    A tipi bağlıdır şablonun herhangi argümanlar bağımlı tip veya ekspresyon tip-depende olan decltype(expression) ile gösterilen tip bağımlı veya değer bağımlı

  • olduğunu ifade nt

Yani B<decltype(..)> ifadesi yazın bağımlı olması durumunda bağlıdır.

[temp.dep.Aşağıdaki formları ifade]/4

İfadeler tip bağımlı asla (ifade tipe göre olamaz çünkü):

Bu durum, ne sentezleme türü bağımlı olabileceğini düşündürmektedir
delete cast-expression 
throw assignment-expression 

.

Gcc ve clang ikisi de yanlış mı?

+0

[temp.dep.constexpr]/p1 ile ilgili nedenleriniz doğru değil. Bir "reinterpret_cast", sabit bir ifadede görünemez, ancak [temp.dep.constexpr]/p3, bir "reinterpret_cast" içeren bir ifadenin muhtemelen değere bağımlı olabileceğini açıkça belirtir. –

+0

'decltype (..)' bir ifade değil. Bu yüzden, [temp.dep.type] /9.8'e de ihtiyacınız var. Bu paragraf sadece 'throw' ve' new' için iyi tanımlanmış * tip bağımlı * olmamak için 'decltype (expression)' ifadesini gerektirir. – dyp

+0

@dyp Evet! Bu kesin gibi görünüyor. – willj

cevap

7

typename gerektiğinde geri dönelim. §14.6 [temp.res]/p3, her tırnak N4140 vardır: bir kalifiye kimliği mevcut örnekleme bir üyesi olan bir türü ifade etmek için tasarlanmıştır

(14.6.2.1) ve iç içe isim belirteci bağımlı bir tipi ile ilgilidir, bu typename-belirtici oluşturan, anahtar kelime typename ile başlayan edilir. Bu durumda

kalifiye kimliğiB<decltype(throw (int*)n)>::Type (ve analiz tam olarak aynı olduğu için delete versiyon). iç içe geçmiş-ad-belirteci ya da B<decltype(throw (int*)n)>::, typename, bağımlı türüne başvuruyorsa gereklidir.

§14.6.2.1 [temp.dep.type]/p8 o

[...]

ise A tipi bağlıdır

olduğunu, ihmal altı ilgisiz mermilerle diyor

(8.7) - şablon adı ya şablon parametre ya da şablon bağımsız değişkenler herhangi bir tip-bağımlı veya değer bağımlı ya da bir bağlı türü veya bir ekspresyon olduğu bir basit şablon kimliği

(8,8) - sentezleme tip bağlıdır decltype(ifade), (14.6.2.2) ile gösterilir.

B<decltype(throw (int*)n)> bir basit şablon kimliği olduğunu. Şablon adı, B, bir şablon parametresi değildir. Tek şablon argümanı, decltype(throw (int*)n), bir ifade değildir, bu nedenle B<decltype(throw (int*)n)>, bağımlı bir türse yalnızca decltype(throw (int*)n) bağımlıdır. decltype(throw (int*)n), sırasıyla, Madde 8.8'e göre, yalnızca throw (int*)n'un türüne bağımlı olması durumunda bağımlıdır. Ama biz biliyoruz ki başına §14.6.2.2 [temp.dep.expr]/p4: Aşağıdaki formların

İfadeler tip bağımlı asla ( çünkü ifadenin tipi bağımlı olamaz):

[...]

::optdeletedökme ifadesi

[...]

throwatama ifade opt

[...]

Dolayısıyla throw (int*)n bağımlı tip değildir ve bu yüzden decltype(throw (int*)n) bağımlı tip değildir ve bu yüzden B<decltype(throw (int*)n)> bağımlı tip değildir ve bu yüzden typenameB<decltype(throw (int*)n)>::Type için gerekli değildir ve bu yüzden evet, bu bir derleyici hatasıdır.

+0

Bugün nihayet benim hatamın ne olduğunu anladım ve cevabınızda doğru olarak belirtildi. decltype (…) 'bir ifade değildir. Bunu asla sorgulamadım ve [temp.dep.constexpr]/1' tarafından rahatsız edildi. :) – Columbo

İlgili konular