2012-11-26 19 views
8
şablonları için initializer_list inşaat destekleyen

, ben makul kolayca initializer_list yapıcı yetki verebilir görünüyor , Örneğin.İsteğe belki sarma konteynerler

int main(int argc, char* argv[]) { 

    holder<std::vector<int>> y{1,2,3}; 
    return EXIT_SUCCESS; 
} 

Ama oldukça açıkçası 'int' veya yuvalanmış value_type typedef yok başka türü olarak T için çalışmaz. Yani, her ikisi de iç içe değer bir değer_tip tipedef tanımlamaz ve std :: initializer_list yapılamazsa, initializer_list kurucusunun yayınlanmaması için bir tür enable_if veya benzer bir hile kullanmak isterim.

holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values) 
    : t_(values) {} 

Herhangi: derleyici (benim durumumda ++ 3.1 çınlama), hala T int geçersiz T :: VALUE_TYPE üzerinde gezileri, çünkü

ben yapmak istedim, ama yine de çalışmıyor "Bu şablona T'nin değer_sayısı üzerinde bir ilkleştirici listesi yapıcısını verin, eğer sadece T değeri bir değer_sayısı tipine sahipse ve T :: değeri_tipi olan bir initializer_list dosyasından yapılandıysa" ifadesini nasıl ifade edeceğine dair düşünceler.

+0

'initializer_list' doğru değerle geçti, yoksa bazı referans türüne göre iletilmesi gereken var mı? ('&&'?) –

+0

@MartinBa: değere geçmek std :: initializer_list' için doğru (ve önerilir). –

+0

Bir 'initializer_list 'sadece bir işaretçi ve bir boyut içerir, bu yüzden bu değeri iletmek için tamam. Verilerin kendisi kopyalanmaz. –

cevap

4

SFINAE sadece şablon parametre subsitution (SFINAE dolayısıyla S) üzerinde çalışır. Aşağıdaki işler:

template<typename T> 
struct holder { 
    T t_; 

    holder() : 
     t_() {} 

    template<typename U = T> 
    holder(typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, 
    std::initializer_list<typename U::value_type>>::type values) 
    : t_(values) {} 

}; 

bir derleyici hatası yol açan daha sonra bütün sınıf (sizin örnekte) türü int için kullanacağımız bir şablon işlevi, kullanmadıysanız. Eğer fazladan şablon parametresi kullanıldığında eğer işlev imzası güzel yapabilir

Not:

template<typename U = T, class = typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, bool>::type> 
    holder(std::initializer_list<typename U::value_type> values) 
    : t_(values) {} 
+0

İlginç, ama işe yaramıyor. Orijinal sürümümde > y = {1, 2, 3} 'düzgün çalışıyor, fakat en azından derleyicimle, gözden geçirilmiş kurucunuz imzanızla çalışmaz. 'Aday kurucu şablonunun uygun olmadığını iddia ediyor: 1 argüman gerektiriyor, ancak 3' ' – acm

+2

' 'sağlandı' 'enable_if'i bırakıp sadece' template tutamacını kullanamazsınız (std :: initializer_list değerler)? –

+0

@VaughnCato daha iyi görünüyor. – acm