2015-12-19 15 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 
} 

Dòng cuối cùng cho lỗi: 17 : error: invalid conversion from 'const char*' to 'char' [-fpermissive]Perfect chuyển tiếp không thành công khi mục tiêu là tổng hợp với mảng

Nếu tôi sử dụng std::forward(args)... thay vì args... sau đó thậm chí còn nhiều lỗi đưa ra; và cũng có lỗi nếu tôi cố gắng sử dụng {'a', 'b', 'c', '\0'} làm trình khởi tạo thay cho chuỗi ký tự.

Có cách nào để thực hiện công việc này, tức là cho phép X z{......}; có bất kỳ điều gì bên trong niềng răng sẽ là trình khởi tạo hợp pháp cho x2, được chấp nhận và thực tế khởi tạo x2?

+0

"* Có cách nào để thực hiện tác vụ này" *, xóa hàm tạo hay sử dụng 'std :: string' làm kiểu' buf' –

+0

viết '' a ',' b ',' c ',' \ 0'' thay vì '" abc "' hoạt động với VS sử dụng C++ 17 –

Trả lời

5

Đây là vấn đề thiết kế bấp bênh được kế thừa từ C++ 98: Các chuyển đổi hoặc khởi tạo nhất định được giới hạn cú pháp thành chữ, trong chuỗi ký tự chuỗi cụ thể như khởi tạo cho mảng char ([dcl.init.string]/1) và số nguyên nguyên như hằng số con trỏ null ([conv.ptr]/1). Điều đó, tất nhiên, không tốt với chuyển tiếp "hoàn hảo".

Đối với con trỏ rỗng, sự cố đã bị phá vỡ bằng cách giới thiệu nullptr, có thể được sử dụng thay vì 0 và hoạt động tốt ngay cả sau khi được chuyển tiếp.

Trong trường hợp của bạn, có cơ bản là hai lựa chọn chính:

  • Khai thác cú đúp sự bỏ bớt - X là một tổng hợp, quá:

    struct X { 
        X2 x2; 
    } z{1, 2, "abc"}; // Ok 
    
  • Khai buf có kiểu lớp, ví dụ std::string hoặc, có lẽ phù hợp hơn trong trường hợp của bạn, một số kích thước tương đương tĩnh (giới hạn kích thước 10).

+0

xin lỗi, tôi có nghĩa là nói chung 'X' sẽ không phải là tổng hợp, ý tưởng của tôi là cho phép không tổng hợp với nhiều dữ liệu công khai vẫn sử dụng việc khởi tạo tổng hợp cho dữ liệu công khai đó –

Các vấn đề liên quan