2016-12-30 18 views
7

constexpr yapıcısına iletilen bir başlatıcı listesinin belirli bir boyutta olduğunu doğrulamak mümkün olabilir mi? Yoksa bu sadece çalışma zamanında yapmak mümkün olabilir mi? Bir initializer listesinin belirli bir boyutta olması statik_assert

Bu

fikir, ama çalışmıyor: Ben VS2015 en std::initializer_list uygulanması ve begin(), end() ve size() baktım

struct group 
{ 
     constexpr group(
      std::initializer_list<std::initializer_list<UINT const> const> groups 
     ) 
     { 
      static_assert(each_list_size_greater_than_1(groups.begin(), groups.end())); 
     } 

     constexpr static bool each_list_size_greater_than_1(
      std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const begin 
      , std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const end) 
     { 
      return begin == end || begin->size() > 1 && each_list_size_greater_than_1(begin + 1, end); 
     } 
}; 

tüm constexpr fonksiyonlardır. Bir std::initializer_list<T> ait size() bir constexpr bir constexpr işlev içinde bir constexpr gibi davranmaya olmaz size() üyesini değerlendirmek rağmen

cevap

9

: onlar başka bir yerde tanıtmak ama değil nerede sadece constexpr ifadesi içinde constexpr gibi davranmaya nesnelerin o kasıtlı olduğunu . Örneğin

: bir constexpr vermek üzere kabul edilir bir değer constexpr başlamadan önce oluşturulan veri bağlıdır (1) İlk durumda

constexpr get_size(std::initializer_list<int> list) { 
    constexpr std::size_t csize = list.size(); // ERROR (1) 
    std::size_t   size = list.size(); // OK 
    return size; 
} 

int main() { 
    constexpr std::size_t csize = get_size(std::initializer_list<int>{ 1, 2, 3 }); // OK (2) 
    // ... 
} 

. Sonuç olarak, constexpr değerini değerlendirmez. İkinci durumda (2), veri constexpr içinde tanımlanmıştır ve bu nedenle sonuç bir constexpr olabilir.

Bu tasarımın yol açan tartışmaların bir parçası olmamıştır ama buna constexpr argümanlar bir constexpr işlevin sonucu türünü değiştirmeyi önlemek için arzu edilir görünüyor: Değerler işlev tanımı içinde constexpr ler olsaydı, Dönüş değeri de constexpr s olur ve bu nedenle dönüş türünde şablon argümanları olarak kullanılabilirler. Bu, farklı tipler sağlayan constexpr işlevine farklı değerlere yol açacaktır. Şimdiye kadar, yalnızca bir fonksiyonun argüman türlerini değiştirerek ve/veya bir fonksiyonun argüman sayısını değiştirerek farklı bir getiri türü elde edebilirsiniz.

+0

Son ifadenizle ne kastedildi: 'Şimdiye kadar, farklı bir döndürme türü yalnızca şablon argümanlarını ve/veya sayılarını değiştirerek olabilirsiniz. – Adrian

+0

@Adrian: C++ standartlarına göre en az C++ 1z'ye kadar, işlev argümanlarının _value_'ına dayalı bir işlev için farklı dönüş türleri oluşturamazsınız. Dönüş türünü değiştirmek için işlevin _type_'ini değiştirmeniz gerekecektir. Aslında bir fonksiyonun dönüş türünü değiştirmeyle ilgilendiğinizi değil, bir argüman değerinin 'constexpr' olarak kullanıldığını düşünmüyorum. Bununla birlikte, bir argüman değeri bir fonksiyon içinde bir "constexpr" olarak kullanılabiliyorsa, geri dönüş türünde aynı değer kullanılabilir, böylece şu anda izin verilmeyen bir şey yapılabilir. –

İlgili konular