それが問題です。
4 に答える
はい。標準 C++ では、va_arg と ... 構文を使用できます。詳細については、MSDN を参照してください。
C++/CLI の場合、これに対するショートカットがあります。
これは次のように行います。
void TheMethod( String^ firstArgument, ... array<Object^>^ variableArgs );
詳細については、このブログ投稿を参照してください。
同じ便利な構文を持つアンマネージ C++ の場合は、いいえ。
ただし、C++ の関数に対する可変引数リストはサポートされています。
基本的に、最後のパラメーターが省略記号 (...) である関数を宣言し、関数の本体内で va_start()/va_arg() 呼び出しを使用して、提供されたパラメーター リストを解析します。
このメカニズムはタイプ セーフではなく、呼び出し元は何でも渡すことができるため、関数のパブリック インターフェイスと渡されると予想されるものを明確に文書化する必要があります。
マネージ C++ コードについては、Reed のコメントを参照してください。
現在、最新の C++ では、可変引数関数に対して最新のタイプ セーフな手法を使用できます。
すべての引数が同じ型の場合は、可変個引数テンプレートまたは std::initializer_list のいずれかを使用します
可変個引数テンプレートでは、再帰を使用して可変個引数リストを調べます。可変個引数テンプレートの例:
template<class T>
void MyFoo(T arg)
{
DoSomething(arg);
}
template<class T, class... R>
void MyFoo(T arg, R... rest)
{
DoSomething(arg);
// If "rest" only has one argument, it will call the above function
// Otherwise, it will call this function again, with the first argument
// from "rest" becoming "arg"
MyFoo(rest...);
}
int main()
{
MyFoo(2, 5.f, 'a');
}
これにより、DoSomething、または MyFoo への再帰呼び出しの前に実行するその他のコードに、関数 MyFoo に渡す各引数の型のオーバーロードがある場合、その正確なオーバーロードが呼び出されることが保証されます。
std::initializer_list では、単純な foreach ループを使用して引数を調べます
template<class T>
void MyFoo(std::initializer_list<T> args)
{
for(auto&& arg : args)
{
DoSomething(arg);
}
}
int main()
{
MyFoo({2, 4, 5, 8, 1, 0}); // All the arguments have to have the same type
}
ブーストには名前付きパラメーターライブラリがあります (C# のパラメーターが何であるかを正しく理解していれば)。次のような関数を書くことができます:
int y = lib::f(_name = "bob", _index = 2);
重要なオーバーヘッドが関係しているかどうかについては何も言えません。