時間:2014.07.01
地點:基地
-----------------------------------------------------------------------------------------
命名空間對函數匹配的影響主要表現在:使用using聲明或using指示能將某些函數添加到候選函數集(不同版本)中。
一、與實參相關的查找與重載
對於接受類類型實參的函數而言,其名字查找是在實參的類所在的命名空間中進行。我們將在實參類以及實參類的基類所屬的命名空間中搜尋候選函數。這些命名空間中所有與被調函數同名的函數都將被添加到候選集中,即使其中某些函數在調用語句處不可見。比如:
namespace NS
{
class Quote{/*......*/};
void Display(const Quote&){/*......*/}
}
在命名空間NS下,我們定義了一個Quote類和Display函數,該函數接受Quote類類型的參數。
class BulkItem:public NS::Quote
{
/*......*/
};
類BulkItem繼承命名空間NS下的類Quoteint main()
{
BulkItem book1;
Display(book1);
return 0;
}
在這裏,我們傳遞給Display的實參是一個類類型BulkItem,於是調用語句的候選函數查找不僅會在調用語句所在的作用域即main()函數中查找,它還會在BulkItem已經其基類Quote所屬的命名空間中查找。即在這裏表現爲命名空間NS中聲明的函數Display(const Quote&)也將被添加到候選函數集當中。從而在這裏可以正確地調用到Display函數。
-----------------------------------------------------------------------------------------
二、重載與using聲明
using NS::print(int); //這樣會編譯錯誤,因爲using不能聲明特定函數
using NS::print; //正確,using在這裏只聲明一個名字
這樣之後,該函數的所有版本都將被引入到當前作用域之中。三、重載與using指示
namespace my_space
{
extern void print(int);
extern void print(double);
}
//接下來是一個普通的函數聲明
void print(const std::string&);
//using指示,它將把該命名空間名字提升到外層作用域,並與外層作用域同名不同參的函數重載,比如在這裏using指示把名字添加到print調用的候選函數集中
using namespace myspace;
//於是現在掉用print函數時有如下候選函數版本
//myspace中的print(int)
//myspace中的print(double)
//當前域中顯式聲明的print(const std::string&)
void FooBar(int ival)
{
print("Value: "); //該句會調用全局函數的print(const string&)
print(ival); //調用命名空間中的print(int)
}
注意using聲明與using指示的區別:四、多using指示與重載
namespace SpaceOne
{
int print(int);
}
namespace SpaceTwo
{
double print(double);
}
//使用using指示從不同的命名空間中創建一個重載函數集合
using namespace SpaceOne;
using namespace SpaceTwo;
//還在當前域中定義一個同名不同參函數
long double print(long double);
int main()
{
print(1); //調用SpaceOne中的print(int)
print(2.1); //調用SpaceTwo中的print(double)
return 0;
}
在上面,全局作用域中,函數print的重載集合中包括print(int),print(double)和print(long double),儘管它們的聲明位於不同作用域中,但他們都屬於mian函數中print調用的候選函數集。