0

次の C++ コードを検討してください

class A
{
public:
  void doStuff() {};
  void callStuff()
  {
    doStuff(true);
    doStuff();
  };
private:
  void doStuff(bool doIt = false) {};
};

int main()
{
  A a;
  a.doStuff();
  a.callStuff();

  return 0;
}

当然のことながら、GCC はこれをコンパイルするときにいくつかのエラーを出します。

overload.cpp: メンバー関数 'void A::callStuff()':                                                                                                                                                                                                                        
overload.cpp:8:10: エラー: オーバーロードされた 'doStuff()' の呼び出しがあいまいです                                                                                                                                                                                                          
  doStuff();                                                                                                                                                                                                                                                                   
          ^                                                                                                                                                                                                                                                                    
overload.cpp:8:10: 注: 候補は次のとおりです。                                                                                                                                                                                                                                       
overload.cpp:4:12: 注: void A::doStuff()                                                                                                                                                                                                                                     
       void doStuff() {};                                                                                                                                                                                                                                                      
            ^                                                                                                                                                                                                                                                                  
overload.cpp:11:12: 注: void A::doStuff(bool)                                                                                                                                                                                                                                
       void doStuff(bool doIt = false) {};
            ^
overload.cpp: 関数 'int main()' 内:
overload.cpp:17:17: エラー: オーバーロードされた 'doStuff()' の呼び出しがあいまいです
       a.doStuff();
                 ^
overload.cpp:17:17: 注: 候補は:
overload.cpp:4:12: 注: void A::doStuff()
       void doStuff() {};
            ^
overload.cpp:11:12: 注: void A::doStuff(bool)
       void doStuff(bool doIt = false) {};
            ^

いくつか質問があります:

  • どのオーバーロードを使用するかをコンパイラに伝えるにはどうすればよいですか? それらのいずれかを削除する必要がありますか?
  • それらのいずれかを削除する必要がある場合、オーバーロードを呼び出さずにコンパイル時にこの問題を見つけるにはどうすればよいですか? それらを呼び出さない限り、すべてが正常にコンパイルされるはずなので、呼び出しようとすると、追加したオーバーロードを呼び出すことができないことが後でわかる場合があります。
  • 2 番目のエラーが発生するのはなぜですか? 関数はmainプライベート オーバーロードにアクセスできないため、使用するオーバーロードを認識している必要があります。
4

3 に答える 3

2

どのオーバーロードを使用するかをコンパイラに伝えるにはどうすればよいですか? それらのいずれかを削除する必要がありますか?

それらの1つを削除または名前変更することはできません。

それらのいずれかを削除する必要がある場合、オーバーロードを呼び出さずにコンパイル時にこの問題を見つけるにはどうすればよいですか? それらを呼び出さない限り、すべてが正常にコンパイルされるはずなので、呼び出しようとすると、追加したオーバーロードを呼び出すことができないことが後でわかる場合があります。

あなたもできません。あいまいさは、引数を使用せずにメンバー関数を呼び出そうとした場合にのみ検出されます。コンパイル時のチェックを実行できたとしても、非常に具体的なチェックが必要であり、オーバーロードの 1 つを削除または名前変更する方が簡単です。

2 番目のエラーが発生するのはなぜですか? メイン関数はプライベート オーバーロードにアクセスできないため、どちらを使用するかを認識している必要があります。

残念ながら、オーバーロードの解決は、アクセス指定子が考慮される前に発生します。したがって、コンパイラは、オーバーロードの 1 つがプライベートであるという事実さえ考慮しません。あいまいな呼び出しは、それが発生する前に検出されます。なぜこれがこのようになるのかはよくわかりませんが、それは標準が言っていることです。

于 2013-08-29T02:53:30.377 に答える
0

デフォルトのパラメータ「bool doIt = false」を削除する必要があります。

class A
{
public:
  void doStuff() {};
  void callStuff()
  {
    doStuff(true);
    doStuff();
  };
private:
  //void doStuff(bool doIt = false) {};
  void doStuff(bool doIt) {};
};

int main()
{
  A a;
  a.doStuff();
  a.callStuff();

  return 0;
}
于 2013-08-29T08:09:05.683 に答える