5

これの最終的な目標は、関数呼び出しで宣言できる、特定の型 (異なる型ではなく同じ型) の可変数の引数を取ることができる関数を持つことです。

Visual Studio 2010 を使用しているため、次のことはできません。

MyFunction({1,2,3});

回答された以前の質問では、 を使用できることがわかりましたが、パラメーターを 1 つだけ渡そうとすると、何らかのバグがあるように思われることがboost::assign::list_of()後でわかりました。

そこで、さらに検索を行ったところ、可変引数関数を使用して目的を達成できることがわかりました。

void TestFunction2<int>(int count, ...)
{}

ただし、タイプで制限したかったので、最終的にテンプレートでこれを行うことができることがわかりました。

template <class T>
void TestFunction(const T& count, ...);

template <>
void TestFunction<int>(const int& count, ...);

残念ながら、varargs のようなものva_listは明らかに参照が好きではありません。このような型を制限するために私が見た例では、const 参照が使用されていました。カウントパラメーターの const 参照の側面を削除すると、希望どおりに機能しますが、これが将来恐ろしい副作用につながるかどうか、またはこの可変引数全体が悪い考えであるかどうかはわかりませんから始めます。

だから私の質問は、上記の最後の例で私がやっていることは良いことですか、それとも悪いことですか? それが悪い場合、たとえばパラメーターのようにインラインで 1 つ以上のパラメーターを使用して関数を呼び出すことができるようにするための良い代替手段は何intですか?

4

2 に答える 2

4

std::initializer_list<T>残念ながら、これにはC++ 11のサポートが必要です。

別の方法として、配列を使用することもできます。

#include <iostream>
 
template <typename T, size_t N>
void func(T (&s)[N]) {
    for (size_t i = 0; i != N; ++i) {
        std::cout << s[i] << '\n';
    }
}
 
int main() {
    int array[] = {1, 2, 3};
    func(array);
}

初期化子リストをサポートするコンパイラに移行すると、これは次のように変更できます

#include <iostream>
 
template <typename T>
void func(std::initializer_list<T> s) {
    for (T const& t: s) {
        std::cout << t << '\n';
    }
}
 
int main() {
    func({1, 2, 3});
}

したがって、関数サイトと呼び出しサイトの更新はどちらも簡単です。

注: コール サイトは、マクロを使用して完全に似たものにすることができます。私はそのようなアプローチに反対することをお勧めします。

于 2013-08-22T11:00:47.140 に答える