2016-10-03 20 views
9

Bunun için bir GCC hatası gönderiyordum, ancak bunu iki kez kontrol etmeyi tercih ediyorum.Brace-initialization vs Parenthesis Bug

#include <utility> 
template<typename T, typename A> 
void F(A&& a) { T(std::forward<A>(a)); } // Note:() syntax. 
int main() { int i; F<int&>(i); } 

ve:

#include <utility> 
template<typename T, typename A> 
void F(A&& a) { T{std::forward<A>(a)}; } // Note: {} syntax. 
int main() { int i; F<int&>(i); } 

Son Clang ve MSVC derleyiciler iki programı kabul

şu programları düşünün. GCC 5 ve ötesi, ilk programı kabul ediyor ancak ikincisini reddediyor, invalid cast of an rvalue expression of type 'int' to type 'int&'.

Bu bir GCC hatası mı? Veya bu gerçekten yukarıdaki bağlamda T{} ve T() arasındaki (ve böylece Clang ve MSVC'de bir hata) arasındaki fark nedir?

Düzenleme: sorun aşağıdaki basit alıntılar için daraltılabilir

:

int i; (int&){i}; 

ve

int i; (int&)(i); 
+0

Adsız bir lvalue başvurusunu tanımlayabilir ve başlatabilir misiniz? Hata zaten yanlış görünüyor. – krzaq

+0

@krzaq: Neden göremiyorum. Ayrıca, bu hatayı 'noexcept' ifadesinde vurdum, bu yüzden bir ifade bağlamındaki durumu anlamak istiyorum. – alecov

+4

Bu, [temel sorun 1288] 'dir (http://wg21.link/cwg1288). GCC'nin kararını uygulamaya koyması gerekiyordu, ama belki de tamamen sabit değildi. –

cevap

6

vardır iki ayrı mesele:

  • Standart T{x}'un T referans tipi için ne yapması gerektiği belirsizdir. Şu anda [expr.type.conv]/1, T türünde bir değer yarattığını söylüyor, bu da referans türleri için anlamsız. Bu core issue 1521.
  • aklı başında olan yaklaşık T __tmp{x}; ve sonra, (lvalue referans T için rvalue referans T ve lvalue için çok xValue) static_cast<T>(__tmp) eşdeğer verim yok başvuru türü T için T{x} olması muhtemelen. Bununla birlikte, yayınlanan C++ 11, referansların liste-başlatması için şartnameyi mahvetti ve her zaman bir geçici oluşturdu. Sonuç int i; int &r{i};'un r'u i geçici bir kopyasına bağlamaya çalıştığı için derlenemediğinden, bu kesinlikle saçmadır. Bu, GCC çözümlemesi gerçekleştirmesi beklenen core issue 1288 ile giderilmiştir, ancak hata iletisinden tamamen düzeltilmemiş gibi görünüyor.