簡體   English   中英

在其命名空間外定義的類成員函數

[英]Class member function defined outside its namespace

以下代碼與godbolt在線編譯器瀏覽器站點上提供的最新MSVC,GCC和CLang完美編譯。 我想知道為什么:

namespace ns
{
    struct Test
    {
        void foo();
    };
}

using namespace ns;

// Alert! Member function defined outside its namespace!
void Test::foo()
{
}

int main()
{
    ns::Test   obj;
    obj.foo();
    return 0;
}

cppreference聲稱如果在其類之外定義成員函數,則必須在該類的名稱空間中定義它。 請參閱有關成員函數的cppreference頁面的最頂部。

但是,編譯器仍接受代碼。 所有三個獨立編譯器都不太可能有相同的bug,對吧? 那么,他們接受這樣的代碼背后有充分的理由嗎?

引用C ++ 17(n4659)12.2.1 [class.mfct] / 1:

出現在類定義之外的成員函數定義應出現在包含類定義的命名空間范圍內。

這意味着它必須在包含該類的命名空間或該命名空間的任何父命名空間中定義。 在您的情況下,它在全局命名空間中定義,它確實包含(間接)類定義。

12.2.1成員函數[class.mfct]

可以在其類定義中定義成員函數(11.4),在這種情況下,它是內聯成員函數(10.1.6),或者如果已經聲明但未在其中定義,則可以在其類定義之外定義它。類定義。 出現在類定義之外的成員函數定義應出現在包含類定義的命名空間范圍內。

並不意味着該定義必須出現在直接圍繞范圍 它可以出現在任何封閉的命名空間中,即使這是幾層。

但是,這將是非法的:

namespace a {
    struct X {
        void Y();
    };
}
namespace b { // not an enclosing namespace
    void X::Y()
    {
        std::cout << "Do a thing!\n";
    }
}

using namespace ns;

5)using-directive:從使用指令之后的任何名稱的非限定名稱查找的角度來看,直到它出現的作用域的結尾,ns_name中的每個名稱都是可見的,就好像它是在最近的封閉中聲明的那樣包含using-directive和ns_name的namespace。

這意味着在當前作用域中,可以省略ns來解決該命名空間內的某些內容。

因此,當您編寫此代碼時:

using namespace std;
vector<string> vectorofstrings;

你不必寫

std::vector<std::string> vectorofstrings;

類的名稱namespace是類的名稱。 所以如果你有:

namespace aNamespace{

class aClass{
    int aMember;
    void aFunction();
};

}

然后完全限定的查找是::aNamespace::aClass並且必須將函數定義為void ::aNamespace::aClass::aFunction(){}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM