[英]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";
}
}
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.