可変長引数の関数について

[戻る]
たけ 2004/11/18(木) 15:11:33
可変長引数の関数の作ろうと以下のコーディングを行ったのですが結果は、va_argsで死んでし
まいます。
可変長部は、0〜3個のCStringを予定しています。

CString CXXX::Test(CString str, int length, ...) {

    va_list args;
    va_start(args, length);

    CString param1, param2, param3;

    if (length > 0) {
        param1 = va_arg(args, CString);
    }
    if (length > 1) {
        param2 = va_arg(args, CString);
    }
    if (length > 2) {
        param3 = va_arg(args, CString);
    }
    〜略
}

Test("str", 3, "aa", "bb", "cc");

Ban 2004/11/18(木) 15:40:12
CXXX::Test ってことはこの関数はクラスのメンバ(thiscall)ですか?
基本的にva_args は cdecl 型の関数でないと使えなかったと思います。

# 気になって見てみたけど、CString::Format @ atlstr.h も中は
# __cdecl になってました。

Ban 2004/11/18(木) 15:41:29
訂正
CString::Format @ cstringt.h

たけ 2004/11/19(金) 13:19:08
ためしに、CXXX::Testに、__cdeclをつけてみたのですが
va_argで死ぬのは変わりませんでした。
何か、__cdeclを指定する場合の注意事項等ありますでしょうか。

tetrapod 2004/11/19(金) 13:45:00
> Test("str", 3, "aa", "bb", "cc");
可変個引数の関数に CString を渡したいのであればこれはダメです。
最初の "str" は原型宣言により暗黙の変換が行われますが、
可変個引数部分においては暗黙の変換は行われません。

Test(CString("str"), 3, CString("aa"), CString("bb"), CString("cc"));
と呼び出したらどうなるでしょうか?

ないしは CXX::Test() のほうで受け取る可変個引数部分を const char * にするか。

tetrapod 2004/11/19(金) 14:45:16
代案
この例では引数の数は最大で3つ、ということになる訳でしょうか?
4つ以上を指定するとエラーになって欲しい、とか?
それならば単純にデフォルト引数を指定するのが簡単。

class CXX { ...
 CString Test(CString s, const TCHAR* arg1=0, const TCHAR* arg2=0, const TCHAR* 
arg3=0);
};
CString CXX::Test(CString s, const TCHAR* arg1, const TCHAR* arg2, const TCHAR* 
arg3) { ... }
const TCHAR* より CString のほうがお好みならそちらでも可。
これなら可変個引数のようにも使えるけど、暗黙の変換が使えるので簡単。

たけ 2004/11/19(金) 15:11:10
[[解決]]
>Test(CString("str"), 3, CString("aa"), CString("bb"), CString("cc"));
>と呼び出したらどうなるでしょうか?
と呼び出したらできました。暗黙の変換が原因だったんですね。

また、デフォルト引数を使う案ですがもちろんできました。
(というか、全然この案思いつかなかったです〜)

デフォルト引数を使う案の方が、引数の数必要ないし、CString("aa")とか書かなくて良いし
こちらを採用することにしました。

わざわざ、代案までありがとうございました。

古いスレッドには追加発言できません。