C++
1int func(int count, ...){ 2 int sum = 0; 3 va_list ap; 4 5 va_start(ap, count); 6 for(int i = 0; i < count; i++) 7 sum += va_arg(ap, int); 8 va_end(ap); 9 return sum; 10}
動作は確認していません。適当に作りました。間違っているかもしれません。
func関数を呼び出す際に、countで引数の個数を入力する必要があります。
めんどうです。
最初に引数の個数をユーザー側で入力せずに、引数の個数をカウントするのはどうやればできるのでしょうか??
すなわち、func関数内でcountを算出するということです!
どなたか教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
すでに variadic template を用いた回答が出ていますが、引数の数をカウントするだけであれば再帰をせずとも sizeof...
を使えば一発で出ます。
template<class... T> int count_arguments(T... args){ return sizeof...(args); } #include <iostream> int main(void) { std::cout << count_arguments(1,2,3) << std::endl; return 0; }
もしも処理系が C++17 に対応しているならば、引数を足し合わせる操作に関してもテンプレートの再帰などといった回りくどいことをしなくても fold expression と呼ばれる形式が利用可能です。
template<class... T> int sum(T... args) { return (args+...); } #include <iostream> int main(void) { std::cout << sum(1,2,3) << std::endl; return 0; }
ただ、 C++17 はまだ非対応の処理系が多いかもしれませんね。
投稿2017/06/02 14:01
総合スコア5714
0
ベストアンサー
すなわち、func関数内でcountを算出するということです!
残念ながら、不可能です。
可変長引数を取る関数に任意個の実引数を渡すには、番兵(sentinel)を用いる実装方式があります。下記コードでは正数のみを有効データとみなしています。
C
1int func(int init, ...) { 2 int sum = init; 3 va_list ap; 4 5 va_start(ap, init); 6 for (;;) { 7 int val = va_arg(ap, int); 8 if (val < 0) 9 break; 10 sum += val; 11 } 12 va_end(ap); 13 return sum; 14} 15 16int main() { 17 int sum = func(1, 2, 3, -1); 18 printf("%d\n", sum); 19} 20
どうしても「個数」を直接取得したい場合、強引に似たようなことを実現できなくもありません。下記コードはC99/C11でしか動作しませんが、count
を自動計算させています。(参考:Cで可変長引数のみを取る関数を作る)
C
1int func_impl(int count, ...) { 2 int sum = 0; 3 va_list ap; 4 5 va_start(ap, count); 6 for(int i = 0; i < count; i++) 7 sum += va_arg(ap, int); 8 va_end(ap); 9 return sum; 10} 11 12#define count_args(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int)) 13#define func(...) func_impl(count_args(__VA_ARGS__), __VA_ARGS__) 14 15int main() { 16 int sum = func(1, 2, 3); 17 printf("%d\n", sum); 18}
おまけ:最新のC++機能をつかうと下記のように書くこともできます。(もはや"個数"が不要なのですが、必要ならsizeof...(args)
で取得可能です)
C++
1#include <stdio.h> 2 3template<typename... Ts> 4int func(Ts... args) { 5 //printf("count=%zu\n", sizeof...(args)); 6 return (args + ...); 7} 8 9int main() { 10 int sum = func(1, 2, 3); 11 printf("%d\n", sum); 12}
投稿2017/06/02 13:42
編集2017/06/02 13:58総合スコア6191
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/02 14:55

0
こんにちは。
C言語機能の範疇では無理です。
しかし、C++11以降で使えるようになったValidac Templateを使えば可能です。「可変長テンプレート」で検索すると使い方の解説がそこそこ出てきます。
ただ、テンプレート+再帰なのでなかなかハードです。でも、使えるようになると結構便利です。
引数の数を数えるだけなら、次のコードでカウントできます。
C++
1#include<iostream> 2 3unsigned count() 4{ 5 return 0; 6} 7 8template<typename tFirst, typename... tTypes> 9unsigned count(tFirst const&, tTypes const&... iRef) 10{ 11 return count(iRef...)+1; 12} 13 14struct Foo { }; 15 16int main() 17{ 18 std::cout << count(1, 2, 3, 4, 5) << "\n"; 19 std::cout << count("abc", Foo()) << "\n"; 20}
でも、これだけでは役に立たないです。まだ結構頑張らないと使えるようになりません。
投稿2017/06/02 13:51
総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/02 14:04