0

C++で

void foo(int i)
{ std::cout<<"int"<<std::endl; }

void foo(float i)
{ std::cout<<"float"<<std::endl; }

void foo(void *i)
{ std::cout<<"void *"<<std::endl; }

void foo(bool b)
{ std::cout<<"bool"<<std::endl; }

void main() { foo(0); }

これをコンパイルすると、エラーが発生します。
visual-studio 2008では、エラーはC2668です:'function':オーバーロードされた関数へのあいまいな呼び出し

私はこの問題が発生する理由を知っており、時間を使用する型キャストの解決策を知っています。しかし、この方法を使用すると関数のオーバーロードの字句性が失われるため、これは適切な解決策ではないと思います。

私のプロジェクトでは、自動型をint、float、std::basic_stringおよび関数ポインターに変更する字句オブジェクトを作成しています。すべての型キャスト演算子と作成者をオーバーロードします。しかし、「NULL」を入力すると、エラーC2668が発生します。

実際、ほとんど問題ありません。唯一の深刻な問題は、FALSEを使用する場合です。私のプロジェクトはコアライブラリであるため、すべてのエンドクライアントプログラマーをガイドすることはできません。

この問題をより賢く解決するための秘訣やヒントを誰が知っていますか?

4

3 に答える 3

2

現在のところ、コードでエラーが発生することはありません。あいまいさはありません。0(an )を渡すと、 (ID変換)が他のどのものよりも適していることはint明らかです(ただし、0は他のすべてのオーバーロードの型に暗黙的に変換することもできます)。foo(int)

私の当面の推測では、テストしているコードは投稿したものとまったく同じではないでしょう。たとえば、オーバーロードを取得していなかっintた場合、あいまいなオーバーロードについてエラーが発生することが予想されます(上記のように0、他のすべてのオーバーロードが取得するタイプへの暗黙の変換があるため)。VC ++ 2008がコードをそのまま受け入れることを確認しました(VC2010とVC11およびg++ 4.7.0のベータ版も同様です)。

余談ですが、main実際にはを返す必要があることに注意してくださいint(ただし、当面の質問とはほぼ確実に無関係です)。

于 2012-05-06T17:37:53.223 に答える
0

FALSEたぶん、0だけでなくtoを定義することもできます((bool)0)(代わりに使用しないのはなぜfalseですか?!)。

また、考えてみると、持っていることf(int *)f(char *)呼び出すことf(NULL) あいまいなので、とにかくキャストが必要です!あなたがそれを言わない限り、コンパイラはあなたの意図を魔法のように知りません。したがって、何かが本質的にあいまいな場合は、キャストしてあいまいさをなくす必要があります。

于 2012-05-06T14:07:55.337 に答える
0

C++11 では、null ポインター定数として機能する新しいキーワード nullptr を導入することで、これを修正しています。これは nullptr_t 型であり、暗黙的に変換可能であり、任意のポインター型またはメンバーへのポインター型と比較できます。bool を除いて、暗黙的に変換したり、整数型と比較したりすることはできません。

于 2014-03-25T05:37:28.247 に答える