5

さて、これは以前に何らかの形で議論されたことがあると確信していますが、私は明らかに愚かすぎてそれを見つけることができません。

まず、va_listやその他のマクロを探していません。私が探しているのは、main-functionパラメーターのようなものです。

ご存知のとおり、デフォルトのプロトタイプは次のとおりです。

int main(int argc, char *argv[]);

今、私は自分のプログラムに似たものが欲しいのですが、正確にはわかりません。

この関数があると仮定しましょう:

void Function(int argc, unsigned short *args[]) {
    for(int i = 0; i < argc; ++i) printf("%hu ", args[i]);
}

そして、私はこの関数呼び出しのようなものが欲しいです:

Function(5, 1, 2, 3, 4, 5);

それはうまくいくでしょうか?va_listの「乱雑さ」も、作成したくないので、次のようにします。

void AnotherFunction() {
    unsigned short Args[] = { 1, 2, 3, 4, 5 };
    Function(5, Args);
}

その場合、単純なポインタだけが必要になるからです。誰かが私を正しい方向に向けてくれませんか?どうもありがとうございます。

編集:貴重なご意見をありがとうございました。今のところ、標準のC / C++では機能しません。問題に対する別のアプローチを探します。

繰り返しになりますが、どうもありがとうございました。

4

6 に答える 6

3

g ++固有のソリューション:

const size_t MAX_ARGS = 42;

void Function(int argc, const unsigned short (&args)[MAX_ARGS])
{
}

int main()
{
    Function(5, {1,2,3,4,5});
}

実際にパラメータが必要ない場合はargc、テンプレートを作成できます。

template<size_t N>
void Function(const unsigned short(&args)[N])
{
    // use N
}

これはC++03で機能します。配列はconstである必要があります。そうでない場合、そのような一時的な初期化子リストを渡すことはできません。関数内の要素を変更する必要がある場合は、コピーを作成する必要があります。

于 2012-10-07T18:39:02.463 に答える
3

C:もタグ付けしているので、Cではいわゆる複合リテラルと組み合わせたマクロを使用できます。

#define  FUNCTION(ARGC, ...) (Function((ARGC), (unsigned short[]){ __VA_ARGS__ }))

va_listこれは、リスト内のすべての式をに変換するため、acient関数よりもタイプセーフunsigned shortです。

最新のC++VA_ARGSには、マクロ前処理フェーズ用のこの機能もあります。しかし、値で初期化される一時的なベクトルをどのように作成するかはわかりません。

于 2012-10-07T18:36:23.730 に答える
2

デフォルトのパラメータを利用します。

Function(int argc, unsigned short *args[], int a = 2, int b = 3, int c = 4) ;

またはあなたがあなた自身のために望むどんなタイプでも。この例の最後の3つのデフォルト値は、関数に渡す必要はありません。このような関数を呼び出すことができます。

Function (argc, args, 5, 4, 3) ;  //have to remember the maximum no. of parameters

なぜあなたがあなたのプログラムでこの種のことをしたいのか分かりません。追加の変数が必要ない場合、なぜそれらをプログラムに含めるのですか?だが

于 2012-10-07T18:27:25.400 に答える
1

このような関数をCで作成するには、va_listやその他のマクロを作成する必要があります。これは、Cからアセンブリへの変換に起因します。アセンブリでは、スタックフレームを「検索」するだけで、関数に渡される引数がさらに増える可能性があります。

ただし、Cでは、関数のプロトタイプ(引数の数とタイプ)を維持しながら使用できる組み込みメカニズムが他にないため、va_listタイプとマクロを使用してこれを行う必要があります。

http://www.gnu.org/software/libc/manual/html_node/Variadic-Functions.htmlを参照してください。

于 2012-10-07T18:34:24.390 に答える
1

これが2つの標準C++ソリューションです。どちらもC++11をサポートするコンパイラが必要です。

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <utility>

template <typename T, typename... Us>
struct first_of_helper {
    typedef T type;
};

template <typename... Ts>
using FirstOf = typename first_of_helper<Ts...>::type;

template <typename... Ts>
void f(Ts&&... args) {
    typedef FirstOf<Ts...> T;
    std::vector<T> v_args{std::forward<Ts>(args)...};
    std::copy(v_args.begin(), v_args.end(), std::ostream_iterator<T>(std::cout, " "));
    std::cout << "\n";
}

template <typename T>
void g(std::initializer_list<T> args) {
    std::copy(args.begin(), args.end(), std::ostream_iterator<T>(std::cout, " "));
    std::cout << "\n";
}

int main() {
    f(1, 2, 3, 4);
    g({1, 2, 3, 4});
}

C ++ 11より前では、唯一の移植可能なソリューションは経由va_argsです。考えてみてください。va_argsもっと単純なコードを書くことができるので必要なかったとしたら、そもそもなぜそれが存在するのでしょうか。

于 2012-10-07T19:22:56.897 に答える
0

C ++で可変引数を実行するには、基本的に2つの方法があります。

  1. va_listなどを使用するCから継承されたvarargs構文。

  2. 引数を渡すためのコンテナを作成します。このコンテナは、配列、std :: vector、std::listなどにすることができます。

パラメータを直接渡し、コンパイラがコンテナを構築できるようにすることで提案されたソリューションは、非常にJava風です。これが、Sun /OracleがJava5にvar-argsを実装することを決定した方法であり、非常に便利な機能であることが判明しました。残念ながら、C++はこの構文afaikをサポートしていません。

于 2012-10-07T18:36:36.097 に答える