Передача переменных аргументов в одной функции другой функции в D - PullRequest
5 голосов
/ 24 сентября 2011

У меня есть переменная функция D-стиля foo(format, ...), которая является оберткой вокруг writefln.Я хотел бы сделать что-то вроде этого:

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

По сути, передавая параметр (ы) с многоточием в writefln.Я понимаю, что это не легко / возможно в C / C ++, но есть ли способ сделать это в D?

Ответы [ 3 ]

4 голосов
/ 24 сентября 2011

Это сделает за вас:

import std.stdio;
void customWrite(Args...)(string format, Args args)
{
    writefln(format, args);
}
4 голосов
/ 24 сентября 2011

Я забыл, что этот тип вариадики даже существовал в D. Я не думаю, что TDPL даже упоминает о них.Я полагаю, что это составляет в общей сложности 4 различных типа вариаций в D.

  1. C вариаций

    extern(C) void func(string format, ...) {...}
    
  2. D вариаций с TypeInfo

    void func(string format, ...) {...}
    
  3. Гомогенные варианты с использованием массивов

    void func(string format, string[] args...) {...}
    
  4. Гетерогенные варианты с использованием шаблонных переменных

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

Я полагаю, что TDPL на самом деле говорит только о # 3 и # 4, и это все, что я обычно использую, поэтому мне придется копать, чтобы выяснить, как передавать аргументыиспользуя № 2.Я ожидаю, что это похоже на то, как вы делаете это в C с # 1, но я не знаю.

Однако это легко сделать с # 3 и # 4.В обоих случаях вы просто передаете args любой функции, которую хотите передать.И то, и другое позволяет индексировать и разделять (например, args[1] и args[1 .. $]), а также иметь свойство length.Таким образом, они просты в использовании, и по большей части, они лучший путь.Единственное исключение, о котором я могу подумать, это если вы вызываете существующую функцию C (в этом случае вы используете # 1) или если вам нужны гетерогенные шаблоны и вы не можете позволить себе увеличение двоичного размера, создаваемого шаблонами (в которомВ случае, если вы используете # 2), что должно быть проблемой только во встроенных средах.В общем, № 3 и № 4, и просто лучшие решения.

3 голосов
/ 24 сентября 2011

Если вам нужны шаблоны, вы можете сделать это следующим образом:

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

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

, но если вы хотите время выполнения переменные аргументы, то вы должны сделать то, что делает C: pass_argptr к "v-версии" вашей функции, например vprintf.

...