在vs2013中,declval
定義如下
template <_Ty>
typenamea dd_rvalue_reference<_Ty>::type declval() _noexcept;
其中,add_rvalue_reference
為一個(gè)traits雕沉,定義為
template <_Ty>
struct add_rvalue_reference
{
typedef _Ty&& type;
}
可見(jiàn),declval
被定義為一個(gè)函數(shù)去件,并且只有申明坡椒,沒(méi)有實(shí)現(xiàn)(在gcc 版本中似乎有實(shí)現(xiàn),但是也不能在運(yùn)行時(shí)調(diào)用——通過(guò)靜態(tài)斷言實(shí)現(xiàn))尤溜。那么倔叼,問(wèn)題來(lái)了,為什么這樣定義呢宫莱,為什么不直接使用模板參數(shù)指定的丈攒,揣測(cè)原因如下:
通過(guò)函數(shù)返回值,實(shí)際上是等同于實(shí)例化了這個(gè)類型的一個(gè)對(duì)像授霸,進(jìn)而可以用這個(gè)對(duì)像調(diào)用成員方法巡验,成員變量。這個(gè)方法最妙的地方在于不論類型的構(gòu)造如何定義甚至有無(wú)構(gòu)造都能獲得這個(gè)類型的一個(gè)對(duì)像的引用實(shí)例碘耳。
其實(shí)显设,也有其它方法可以得到類似的效果。
class Klass
{
public:
int m_a;
//parameter defined
//member function
}
假如有上的一個(gè)類辛辨,可以通過(guò)下面的方法引用到成員變量m_a:
((Klass*)0)->m_a;
這也是在c語(yǔ)言中獲取結(jié)構(gòu)體成員的地址偏移量的常用技巧捕捂,但是有魔鬼數(shù)字和類型強(qiáng)轉(zhuǎn),不如declval
來(lái)得優(yōu)雅斗搞。
當(dāng)然這一切都只能是在編譯期蹦噠指攒。declval
常和c++11新引入的decltype配合,可以參考這篇文章僻焚。
以上允悦。
僅做個(gè)人記錄之用,謬誤之處溅呢,歡迎拍磚澡屡。