2

次のヘッダー ファイル (c++) を使用することを検討してください。myclass.hpp

#ifndef MYCLASSHPP_
#define MYCLASSHPP_

namespace A {
namespace B {
namespace C {

class myclass { /* Something */ };

myclass& operator+(const myclass& mc, int i);

}}}

#endif

実装ファイルを考えてみましょう:myclass.cpp

#include "myclass.hpp"
using namespace A::B::C;

myclass& operator+(const myclass& mc, int i) {
   /* Doing something */
}

メインファイルを検討してください:main.cpp

#include "myclass.hpp"

int main() {
   A::B::C::myclass el = A::B::C::myclass();
   el + 1;
}

さて、リンカーは、未定義の参照があることを教えてくれますA::B::C::operator+(A::B::C::myclass const&, int)

ここで何が問題なのですか?

4

3 に答える 3

6

実装ファイルにいるからといってusing namespace A::B::C、そこで宣言されているすべてが自動的に名前空間にあるわけではありません(そうしないと、名前空間が複数A::B::Cある場合、すべての定義があいまいになります)。using

myclass.cpp は次のようになります。

namespace A {
namespace B {
namespace C {
    myclass operator+(const myclass& mc, int i) {
        // ...
    }
}

または(私はこのクリーナーを見つけます):

using namespace A::B::C;

myclass A::B::C::operator+(const myclass& mc, int i) {
    // ...
}

現在、コンパイラは、名前空間で 1 つのoperator+関数を宣言し、名前空間にまったくないA::B::Cの関数を定義したと見なし、リンク エラーにつながります。

于 2012-07-06T04:10:50.950 に答える
5

ディレクティブは、名前のusing namespace検索順序を変更します。定義が配置される場所は変わりません。

operator+間違った名前空間で定義しました。

于 2012-07-06T04:11:19.063 に答える
1

「using」キーワードは、呼び出されたメソッドを解決するためにのみ役立ちます。メソッド定義時には使用できません。あなたのステートメントは、実際にはグローバル名前空間でメソッドを定義しているだけです。あなたの定義は次のとおりです。

A::B::C::myclass A::B::C::operator+(const myclass& mc, int i) {
   /* Doing something */
}

メソッドを呼び出すと、次の両方が同じことを行います。

using namespace A::B::C;
myclass tmp;
tmp + 1;

-また-

A::B::C::myclass tmp;
tmp + 1;

お役に立てれば...

于 2012-07-06T04:22:14.250 に答える