2014-12-16 32 views
53

Bu, aşağıdaki soruların bir devamı niteliğindedir: Is it legal to declare a constexpr initializer_list object?.Neden "std :: initializer_list" bir literal tür olarak tanımlanmadı?

C++ 14'ten beri, std::initializer_list sınıfı, constexpr ile işaretlenmiş tüm yöntemlerini içerir. Bir örneği constexpr std::initializer_list<int> list = {1, 2, 3}; yaparak başlatabilmek doğal görünebilir, ancak Clang 3.5, list hakkında sürekli bir ifade ile başlatılmayabilir. As dyp pointed out in a comment, std::initializer_list için herhangi bir gereklilik, özelliklerden yok sayılmış bir tür olarak görülüyor.

Bu şekilde başlatılamıyorsak, tam olarak Constexpr olarak tanımlanan bir sınıfa sahip olmanın amacı nedir? Standartta bir gözetim midir ve gelecekte de sabitlenecek mi?

+0

Richard Smith, burada (http: //clang-developers.42468.n3.nabble.com/C-11-constexpr-ve-initializer-list-td4031078.html) 'std :: initializer_list' kelimesi bir tür haline getirildi. Ancak, Standartta böyle bir gereklilik bulamıyorum. Yukarıda bahsettiğim sorularıma bir yorum gönderdiğim ikinci bir soru, "Statik olmayan üye işlevleri, sözel olmayan türlerin üyeleri olarak bildirilebilir mi?" *, Bkz. [CWG DR 1684] (http: //open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684) – dyp

+0

Bu, garip, clang ++ bunu global kapsam içine koyduğunuzda derler: http://coliru.stacked-crooked.com/a/dab2834181fb8ea4 (Bu [clang bug 15117] idi (http://llvm.org/bugs/show_bug.cgi?id=15117)) Bana başka bir derleyici hata gibi kokuyor. – dyp

+0

clang ++ ayrıca yerel bir statik değişken olduğunda kabul eder: http://coliru.stacked-crooked.com/a/700cf33e2446b63c – dyp

cevap

5

Standart komite, bir hazır tür olmak üzere initializer_list modelini kullanmayı düşünmektedir. Ancak, açık bir gereklilik gibi görünmüyor ve standartta bir hata gibi görünüyor. aşağıdaki özelliklerden hepsine sahip bir sınıf tipi (Madde 9) -
: § 3.9.10.5 kaynaktan

: bu ise,

A tipi bir değişmez tip olan
- - bir toplama tipi (8.5.1) veya bir kopyalama veya taşıma yapıcı değildir, en azından bir constexpr yapıcı veya yapıcı şablonu vardır ve
- - - bu önemsiz bir yıkıcı,
var - onun olmayan tüm -statik veri üyesi s ve taban sınıfları, uçucu olmayan türden türlerdir. 18.9.1 § itibaren

:

namespace std { 
    template<class E> class initializer_list { 
    public: 
    /* code removed */ 
    constexpr initializer_list() noexcept; 
    // No destructor given, so trivial 
    /* code removed */ 
    }; 
} 

Bu birinci ve ikinci gereksinimlerini karşılar.

kaynaktan 18.9.2 § (vurgu benim):

tip initializer_list<E> bir amacı, tip const E nesnelerinin bir dizi erişim sağlar da üçüncü gereksinimi için

. [Not: Bir çift işaretçi veya bir işaretçi artı uzunluğu, initializer_list için açık temsillerdir. initializer_list, 8.5.4'te belirtildiği gibi başlatıcı listelerini uygulamak için kullanılır. Bir başlatıcı listesinin kopyalanması, alttaki öğeleri kopyalamaz.
-end not]

Yani uçucu olmayan edebi türleri olmak initializer_list uygulanmasının özel üyeleri için bir gereksinim yoktur; bununla birlikte, bir çift işaretçi veya bir işaretçi ve bir uzunluğun "açık temsil" olacağına inandıklarından, muhtemelen birisinin initializer_list üyelerine gayri resmi bir şey koyabileceğini düşünmediklerini belirtmişlerdir. Muhtemelen, hem argoda hem de standartta bir hata olduğunu söyleyebilirim.