2

次のコードを持っている:

template<typename T, typename OutStream = std::ostream> struct print {
  OutStream &operator()(T const &toPrint, OutStream &outStream = std::cout) const {
    outStream << toPrint;
    return outStream;
  }
};

この呼び出しは誤りです:

print<int>(2);

エラーメッセージ:

1>main.cpp(38): error C2440: '<function-style-cast>' : cannot convert from 'int' to 'print<T>'
1>          with
1>          [
1>              T=int
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

この呼び出しは誤りではありません:

print<int> intPrinter;
intPrinter(2);

インスタンス化せずに関数オブジェクトを使用できますか?部分的な特殊化機能が必要なため、ここではテンプレート関数を使用できません。

4

2 に答える 2

6

言いたいと思います

print<int>()(2);

ここで、最初の親は(ゼロ引数)コンストラクターを呼び出して一時print<int>オブジェクトを作成し、次に2番目の親は実際にそのオブジェクトの関数呼び出し演算子を呼び出します。あなたが今得ているエラーは、

print<int>(2);

2をに変換する型キャスト式として解釈されprint<int>ます。これはあなたが望むものではありません(そしてまた合法ではありません)。

お役に立てれば!

于 2012-02-05T19:49:13.400 に答える
5

これらのステートレスラッパークラスの場合、静的メンバー関数を使用する方がよい場合があります。

template<typename T, typename OutStream = std::ostream>
struct printer
{
    static OutStream & print()(T const &toPrint, OutStream &outStream = std::cout)
    {
        outStream << toPrint;
        return outStream;
    }
};

次に、でそれらを呼び出すことprinter<Foo>::print(x);ができ、通常、型を推測するヘルパー関数テンプレートを提供できます。

template <typename T> std::ostream & print(T const & x)
{
    return printer<T, std::ostream>::print(x);
}

今、あなたはただ言うことができますprint(x);

于 2012-02-05T19:51:45.087 に答える