2015-12-19 19 views
7
#include <iostream> 

struct X2 
{ 
    int i; 
    int j; 
    char buf[10]; 
}; 

X2 glob{1,2,"abc"}; // OK 

struct X 
{ 
    X2 x2; 

    template<typename... Args> 
    X(Args&&... args): x2{args...} {} 
}; 

int main() 
{ 
    X x;    // OK 
    X y{1, 2};   // OK 
    X z{1, 2, "abc"}; // error 
} 

son satırı verir hata: 17 : error: invalid conversion from 'const char*' to 'char' [-fpermissive]Mükemmel yönlendirme başarısız

Ben std::forward(args)... yerine args... kullanımı o zaman bile daha fazla hata gelip; ve ayrıca dize değişmezi yerine {'a', 'b', 'c', '\0'} başlatıcı olarak kullanmaya çalışırsam hatalar vardır.

bu işi yapmak için bir yol var mı, yani x2 için yasal başlatıcı olacağını parantez içindeki her şeyi, kabul edilir ve x2 başlatmak aslında yok X z{......}; izin?

+0

"* bu işi yapmak için bir yol var mı", * yapıcısı kaldırabilir veya –

+0

yazma ' 'a', 'b' buf'' türü olarak 'std :: string' kullanın' c ',' \ 0 'yerine "abc", C++ 17 –

cevap

5

Bu, C++ 98'den devralınan güvencesiz bir tasarım sorunudur: Belirli dönüşümler veya başlatmalar, söz dizimi, özellikle diziler için başlangıç ​​dizileri ([dcl.init.string]/1) gibi dize hazırlıkları ile sözdizimsel olarak kısıtlanmıştır ve boş işaretçi sabitleri olarak tamsayı değişmezleri ([conv.ptr]/1). Tabii ki, "mükemmel" iletme ile iyi gitmiyor.

Sıfır göstericiler için, 0 yerine kullanılabilen nullptr tanıtılarak sorun giderildi ve iletildikten sonra bile iyi çalışıyor. Senin durumunda

, temel olarak iki ana seçenek vardır:

  • bağ elision Exploit - X bir toplamıdır de:

    struct X { 
        X2 x2; 
    } z{1, 2, "abc"}; // Ok 
    
  • sınıf türünü örneğin olması buf beyan std::string ya da sizin durumunuz için belki de daha uygun, bazı statik boyutlarda eşdeğer (10 ile sınırlı).

+0

kullanarak çalışır, ben genel olarak' X' genel olarak bir araya gelmez, benim düşüncem agregatlara izin vermemek Herkese açık veriler için bu toplu verilere toplu başlatma özelliğini kullanmaya devam etmek –

İlgili konular