2011-09-23 43 views
5

Tôi có hàm kiểu Dariad Dd foo(format, ...), là một trình bao bọc xung quanh writefln. Tôi muốn làm một cái gì đó như thế này:Truyền đối số variadic trong một hàm đến một hàm khác trong D

foo(format, <...>) { 
    //... 
    writefln(format, ...); 
} 

Về cơ bản, chuyển sang tham số dấu chấm lửng (s) để ghi. Tôi hiểu rằng điều này là không dễ dàng/có thể trong C/C++, nhưng có cách nào để thực hiện điều này trong D?

+0

Cảm ơn tất cả, nó chỉ ra các mẫu giải quyết vấn đề rất sạch sẽ và thanh lịch. Tiền thưởng được thêm vào: nó không gây ra bất kỳ sự phân bổ bộ nhớ nào, do đó nó có thể được gọi từ các destructors (đó là một hàm từ một mô-đun ghi nhật ký). –

Trả lời

4

này sẽ làm điều đó cho bạn:

import std.stdio; 
void customWrite(Args...)(string format, Args args) 
{ 
    writefln(format, args); 
} 
3

Nếu bạn muốn mẫu, bạn có thể làm điều đó như thế này:

auto bar(T...)(T args) { ... } 

auto foo(T...)(T args) 
{ 
    return bar!T(args); 
} 

nhưng nếu bạn muốn thời gian chạy luận variadic, sau đó bạn phải làm những gì C không: pass _argptr đến "v -version "của chức năng của bạn, ví dụ vprintf.

+0

Nó có thể là 'bar (args)'. Bạn không nên cần '! T'. –

+1

@JonathanMDavis: Vâng, tôi nhận ra điều đó. Nhưng tôi luôn viết nó một cách rõ ràng khi gọi một generic từ cái khác vì nó thường làm cho các lỗi biên dịch dễ tìm hơn.(Thay vì nói "Tôi không thể tìm thấy một trận đấu", nó thực sự cho bạn biết những gì nó không thể phù hợp.) – Mehrdad

+0

@Mehrdad: một kỹ thuật đáng chú ý! – vines

4

Tôi đã quên rằng những loại variadics thậm chí tồn tại D. Tôi không nghĩ rằng TDPL thậm chí đề cập đến chúng. Tôi tin rằng điều đó làm cho một tổng cộng của 4 loại khác nhau của variadics trong D.

  1. C variadics

    extern(C) void func(string format, ...) {...} 
    
  2. D variadics với TypeInfo

    void func(string format, ...) {...} 
    
  3. variadics đồng nhất sử dụng mảng

    void func(string format, string[] args...) {...} 
    
  4. variadics không đồng nhất với các mẫu thiết variadics

    void func(T...)(string format, args) {...} 
    

Tôi tin rằng TDPL thực sự chỉ nói về # 3 và # 4, và đó là tất cả mà tôi thường sử dụng, vì vậy tôi sẽ phải đi đào bới để tìm ra cách vượt qua đối số bằng cách sử dụng # 2. Tôi hy vọng rằng nó tương tự như cách bạn làm điều đó trong C với # 1, nhưng tôi không biết.

Tuy nhiên, thật dễ dàng với # 3 và # 4. Trong cả hai trường hợp, bạn chỉ cần vượt qua args cho bất kỳ chức năng nào bạn muốn chuyển. Và cả hai đều cho phép lập chỉ mục và cắt (ví dụ: args[1]args[1 .. $]) cũng như có thuộc tính length. Vì vậy, chúng dễ sử dụng, và phần lớn, chúng là cách tốt hơn để đi. Các ngoại lệ duy nhất mà tôi có thể nghĩ đến là nếu bạn đang gọi hàm C hiện có (trong trường hợp này, bạn sử dụng # 1) hoặc nếu bạn cần mẫu không đồng nhất và không đủ khả năng tăng kích thước nhị phân mà mẫu tạo (trong đó trường hợp bạn sử dụng # 2), điều này thực sự chỉ là một vấn đề trong môi trường nhúng. Nói chung, # 3 và # 4 và chỉ là giải pháp đơn giản hơn.

+1

Nhìn xa hơn một chút xuống http://www.d-programming-language.org/function.html#variadic: # 3 cũng hoạt động với các lớp. – BCS

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