2009-07-20 41 views

Trả lời

16

Đối với C++ không được quản lý với cùng cú pháp thuận tiện, không.

Nhưng có hỗ trợ cho variable argument lists để hoạt động trong C++.

Về cơ bản, bạn khai báo hàm có tham số cuối cùng là dấu ba chấm (...) và bên trong hàm sử dụng lệnh va_start()/va_arg() để phân tích cú pháp danh sách tham số được cung cấp.

Cơ chế này không phải là loại an toàn, và người gọi có thể vượt qua bất cứ điều gì, vì vậy bạn nên ghi rõ giao diện nào của hàm và những gì bạn mong đợi để được thông qua vào.

Đối với quản lý ++ mã C, xem ý kiến ​​của Reed .

19

Có. Trong tiêu chuẩn C++, bạn có thể sử dụng cú pháp va_arg và .... Xem MSDN for details.

Đối với C++/CLI, Có một lối tắt cho việc này.

Bạn làm điều này như:

void TheMethod(String^ firstArgument, ... array<Object^>^ variableArgs); 

Xem blog post for details này.

+0

Rất vui được biết về điều đó ... đã không biết C++ có phần mở rộng này cho mã được quản lý. – LBushkin

+0

@LBushkin: Cập nhật cú pháp tốt hơn. –

0

Có thư viện named parameters đang tăng (nếu tôi hiểu chính xác tham số trong C# là gì). Nó cho phép các chức năng viết như thế này:

int y = lib::f(_name = "bob", _index = 2); 

Không thể nói bất cứ điều gì về việc có một phí tổn đáng kể liên quan.

+1

C# params không được đặt tên params - đó là danh sách đối số độ dài biến. –

3

Ngày nay, với C++ hiện đại, bạn có thể sử dụng các phương pháp an toàn loại hiện đại cho các hàm variadic.

Sử dụng một trong hai mẫu variadic hoặc std :: initializer_list nếu tất cả các đối số của bạn có cùng loại

Với mẫu variadic, bạn sử dụng đệ quy phải đi qua một danh sách tham số variadic. Variadic mẫu ví dụ:

template<class T> 
void MyFoo(T arg) 
{ 
    DoSomething(arg); 
} 
template<class T, class... R> 
void MyFoo(T arg, R... rest) 
{ 
    DoSomething(arg); 
    // If "rest" only has one argument, it will call the above function 
    // Otherwise, it will call this function again, with the first argument 
    // from "rest" becoming "arg" 
    MyFoo(rest...); 
} 

int main() 
{ 
    MyFoo(2, 5.f, 'a'); 
} 

Điều này đảm bảo rằng nếu DoSomething hoặc bất kỳ mã khác bạn chạy trước khi cuộc gọi đệ quy để MyFoo, có một tình trạng quá tải cho các loại mỗi đối số bạn vượt qua đến chức năng MyFoo, rằng tình trạng quá tải chính xác sẽ được gọi.

Với std :: initializer_list, bạn sử dụng một vòng lặp foreach đơn giản để đi qua các đối số

template<class T> 
void MyFoo(std::initializer_list<T> args) 
{ 
    for(auto&& arg : args) 
    { 
     DoSomething(arg); 
    } 
} 
int main() 
{ 
    MyFoo({2, 4, 5, 8, 1, 0}); // All the arguments have to have the same type 
} 
+0

Có thể đáng chú ý là bạn cũng có thể kết hợp các mẫu 'static_assert' và variadic để làm cho bạn sở hữu danh sách khởi tạo linh hoạt. F.ex. bạn có thể kết hợp 'std :: is_base_of' với một static_assert trên' T' trong ví dụ của bạn để đảm bảo rằng tất cả các kiểu được bắt nguồn từ một lớp cơ sở nhất định. – atlaste

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