17.2.6 重載與命名空間
1. 候選函數與命名空間
有一個或多個類類型形參的函數的名字查找包括定義每個形參類型的命名空間。這個規則還影響怎樣確定候選集合,為找候選函數而查找定義形參類(以及定義其基類)的每個命名空間,將那些命名空間中任意與被調用函數名字相同的函數加入候選集合。即使這些函數在調用點不可見,也將之加入候選集合。將那些命名空間中帶有匹配名字的函數加入候選集合。
namespace Andersoft
{
namespace Namespace7
{
class Class1{};
void Method1_Class1(Class1 &c1){}
}
namespace Namespace8
{
class Class1:public Andersoft::Namespace7::Class1{};
}
}
namespace Andersoft
{
namespace Namespace7
{
class Class1{};
void Method1_Class1(Class1 &c1){}
}
namespace Namespace8
{
class Class1:public Andersoft::Namespace7::Class1{};
}
}Andersoft::Namespace8::Class1 &c1=Andersoft::Namespace8::Class1();
Method1_Class1(c1);
Andersoft::Namespace8::Class1 &c1=Andersoft::Namespace8::Class1();
Method1_Class1(c1);2. 重載與using聲明
namespace Andersoft
{
namespace Namespace6
{
void Method2_Class1(int &i){}
void Method2_Class1(double &i){}
}
}
namespace Andersoft
{
namespace Namespace6
{
void Method2_Class1(int &i){}
void Method2_Class1(double &i){}
}
}using Andersoft::Namespace6::Method2_Class1;
int i=10;
Method2_Class1(i);
using Andersoft::Namespace6::Method2_Class1;
int i=10;
Method2_Class1(i);3. 重載與using指示
using指示將命名空間成員提升到外圍作用域。如果命名空間函數與命名空間所在的作用域中聲明的函數同名,就將命名空間成員加到重載集合中。
4. 跨越多個using指示的重載
如果存在許多using指示,則來自每個命名空間的名字成為候選集合的組成部分。
//Namespace3.h
#ifndef NAMESPACE3_H
#define NAMESPACE3_H
#include <string>
using std::string;
namespace Andersoft
{
namespace Namespace6
{
void Method2_Class1(int &i){}
void Method2_Class1(double &i){}
}
}
namespace Andersoft
{
namespace Namespace7
{
void Method2_Class1(double &i, string &j){}
}
namespace Namespace8
{
void Method2_Class1(double &i, int &j){}
}
}
#endif
//Namespace3.h
#ifndef NAMESPACE3_H
#define NAMESPACE3_H
#include <string>
using std::string;
namespace Andersoft
{
namespace Namespace6
{
void Method2_Class1(int &i){}
void Method2_Class1(double &i){}
}
}
namespace Andersoft
{
namespace Namespace7
{
void Method2_Class1(double &i, string &j){}
}
namespace Namespace8
{
void Method2_Class1(double &i, int &j){}
}
}
#endifint i=10;
Method2_Class1(i);
double j=10.0;
Method2_Class1(j);
string k="123";
Method2_Class1(j,k);
Method2_Class1(j,i);
int i=10;
Method2_Class1(i);
double j=10.0;
Method2_Class1(j);
string k="123";
Method2_Class1(j,k);
Method2_Class1(j,i);17.2.7 命名空間與模板
模板的顯式特化必須在定義通過模板的命名空間中聲明,否則,該特化將與它所特化的模板不同名。
有兩種定義特化的方式:一種是重新打開命名空間並加入特化的定義,可以這樣做是因為命名空間的定義是不連續的;或者,可以用與命名空間定義外部定義命名空間成員相同的方式來定義特化:使用命名空間名字限定的模板名定義特化。
為了提供命名空間中所定義模板的自己的特化,必須保證在包含原始模板定義的命名空間中定義特化。
namespace Andersoft
{
namespace Namespace9
{
template<class T>
class TC
{
public:
T i;
};
}
}
namespace Andersoft
{
namespace Namespace9
{
template<class T>
class TC
{
public:
T i;
};
}
}using namespace Andersoft::Namespace9;
int _tmain(int argc, _TCHAR* argv[])
{
TC<int> tc1;
tc1.i=10;
TC<string> tc2;
tc2.i="123";
return 0;
}
摘自 xufei96的專欄