2
template <typename T> void function(T arg1, 
    T min = std::numeric_limits<T>::min(),
    T max = std::numeric_limits<T>::max())
{
}

template <> void function<int>(int arg1, int min,int max)
{
}

int main(int argc,char* argv[])
{
    function<int>(1);
}

トークンの関数のデフォルトの引数行に構文エラーC2689およびC2059が表示され::ます。しかし、専門性がなければ、うまくいきます。そして、デフォルトの引数を変更しても、まだ特殊化を行っている場合:

template <typename T> void function(T arg1, 
    T min = T(0),
    T max = T(1))
{
}
template <> void function<int>(int arg1, int min,int max)
{
}

問題もなくなりました。

今、私がこのようにそれを使用する場合:function<int>(1,2,3);またはfunction<float>(1.0f)それは素晴らしいので、テンプレート関数が特殊化されている場合、それを呼び出すときにデフォルトの引数を書き直す必要があるようです?

しかし、2番目のケースでは、呼び出し時に構文エラーがないstd::numeric_limits<T>::..状態に置き換えますが、それはなぜですか?T(..)function<int>(1)

(私はVisual Studio 2010 x64を使用しています)

元の問題はバグが原因であるため、質問は現在、それを回避する方法に変更されていますか?

4

3 に答える 3

3

コードに問題はありません。Comeau Online、Intel C ++ 11.1、およびg++4.1.2は正常にコンパイルします。

コンパイラのバグだと思います。私は最近、Visual C ++ 2010コンパイラに対して、関連しているがわずかに異なるバグレポートを提出しました。


回避策として、呼び出しをラップすることができます。

template <typename T>
T get_limits_min() { return std::numeric_limits<T>::min(); }

template <typename T>
T get_limits_max() { return std::numeric_limits<T>::max(); }

template <typename T> void function(T arg1, 
    T min = get_limits_min<T>(),
    T max = get_limits_max<T>())
{
}

ぶさいくな?とても。


Microsoft Connectで報告されたバグに対応して、次の記事を投稿しました。

プライマリテンプレートには、デフォルトの引数値を持つパラメータが必要です。デフォルトの引数値は、グローバル名前空間にないクラステンプレートのメンバー関数である必要があります。

以下は、再現するための最小限のコードです。

namespace N
{
    template <typename T>
    struct S
    {
        static T g() { return T(); }
    };
}

template <typename T> void f(T = N::S<T>::g()) { }

template <> void f<>(int) { }

int main()
{
    f<int>();
}

コンパイラは、プライマリテンプレートが定義されている行の両方で、次のエラーを発行します。

error C2589: '::' : illegal token on right side of '::'
error C2059: syntax error : '::'

興味深いことに、クラステンプレートがグローバル名前空間にある場合は別の問題があります。次のコードが与えられます:

template <typename T>
struct S
{
    static T g() { return T(); }
};

template <typename T> void f(T = ::S<T>::g()) { }

template <> void f<>(int) { }

int main()
{
    f<int>();
}

コンパイラは、プライマリテンプレートが定義されている行で次のエラーを発行します。

error C2064: term does not evaluate to a function taking 0 arguments

これらのサンプルテストケースは両方とも、整形式のC++プログラムです。

于 2010-08-04T03:25:58.723 に答える
2

https://stackoverflow.com/a/13566433/364084およびhttps://stackoverflow.com/a/27443191/364084でここに回答されているように、これはWindowsヘッダーで定義された最小および最大マクロによるものです。次のコードは、マクロの展開を防ぐことで機能するはずです。

template <typename T> void function(T arg1, 
    T min = (std::numeric_limits<T>::min)(),
    T max = (std::numeric_limits<T>::max)())
{
}

template <> void function<int>(int arg1, int min,int max)
{
}

int main(int argc,char* argv[])
{
    function<int>(1);
}
于 2016-10-10T04:51:48.130 に答える
0

これは正常にコンパイルされています...ComeauOnline、http://codepad.org、EDGコンパイラ、およびG++で。

于 2010-08-04T05:38:10.443 に答える