最近、私は1つの引数を受け付けるテンプレートコンストラクタを持つクラスを持つときに奇妙な振る舞いに遭遇しました。特定の状況下では、このクラスは初期化に失敗します。非常に奇妙な振る舞い:1つの引数のみを持つテンプレートコンストラクタを持つクラス
#include <iostream>
struct Foo
{
template<typename T>
Foo(const T& x)
{
std::cout << "--" << x << std::endl;
}
};
int main(int, char**)
{
Foo f(std::string());
std::cout << "++" << f << std::endl;
return 0;
}
あなたが見るコンストラクタを持つFoo構造です。 mainでは、空のstd :: stringを持つ新しいFooインスタンスを作成します。この例はコンパイルされ、出力は次のようになります。
++1
WTF?あなたが気づいたかもしれないので、これにはという3つの問題があります。最初にコンストラクタは呼び出されませんでした.2番目にfは "1"として出力されました.3番目に、オーバーロードされたオペレータ< <は、コンパイラが一度も不平を言わずにcoutを使用してFooを出力します。つまり、fはFooの型ではありません。
私は少し例を変更します。
int main(int, char**)
{
Foo f(std::string(""));
std::cout << "++" << f << std::endl;
return 0;
}
...と、コンパイラはそこには、オーバーロードオペレータ< <はありません、それが正常であることを示すエラーがスローされます。
--Hello
、それが再び普通です:
int main(int, char**)
{
Foo f(std::string("Hello"));
return 0;
}
今出力されます。
問題は、std :: string()またはfloat()またはany_type()であるかどうかにかかわらず、Foo :: Fooに空のオブジェクトを渡すときです。私はGCC 4.4と4.6でその例をテストしましたが、私はこの動作が非常に予期しないものであることを発見しました。
あなたの意見は?これはGCCのバグですか、私はここに何か不足していますか?
私はそれが関数ポインタとして 'f'を解釈していると思いますが、なぜ私は明確ではありません。たとえば、これも 'Foo f = Foo(std :: string);' –
の例をコピーして貼り付けます.Video Studio 2010ではリンクされません。 –