C++11 用戶自定義數(shù)據(jù)標識

本文根據(jù)眾多互聯(lián)網(wǎng)博客內(nèi)容整理后形成,引用內(nèi)容的版權(quán)歸原始作者所有,僅限于學習研究使用,不得用于任何商業(yè)用途。

用戶定義數(shù)據(jù)標識(User-defined literals)

C++提供了許多內(nèi)建數(shù)據(jù)類型的數(shù)據(jù)標識(2.14節(jié)變量):

123    // int整型
1.2    // double雙精度型
1.2F    // float浮點型
’a'    // char字符型
1ULL    // unsigned long long64位無符號長整型
0xD0    // hexadecimal unsigned十六進制無符號整型
"as"    // string字符串

但是在C++98中并沒有為用戶自定義的變量類型提供數(shù)據(jù)標識。這就違反甚至沖突于“用戶自定類型應該和內(nèi)建類型一樣得到支持”的原則。在特殊情況下,人們有以下的需求:

"Hi!"s            //字符串,不是“以零字符為終結(jié)的字符數(shù)組”
1.2i            //虛數(shù)
123.4567891234df    //十進制浮點型(IBM)
101010111000101b    //二進制
123s            //秒
123.56km          //不是英里(單位)
1234567890123456789012345678901234567890x        //擴展精度

C++11通過在變量后面加上一個后綴來標定所需的類型以支持“用戶定義數(shù)據(jù)標識”,自字義后綴用operator""定義,就是一種特殊的函數(shù)。后綴名必須以下劃線開頭,因為沒有下劃線的后綴是留給std用的。后綴的參數(shù)只能是unsigned long long、long double、const char或者const char + size_t。沒了,它就是這么簡單易上手又很實用的特性。一般來說適合編為后綴的是單位,如kg,km。例如:

constexpr complex operator "" i(long double d)    // 設計中的數(shù)據(jù)標識
{
    return {0,d};    //complex是一個數(shù)據(jù)標識
}

// 將n個字符構(gòu)造成字符串std::string對象的數(shù)據(jù)標識
std::string operator""s (const char* p, size_t n)    
{
    return string(p,n);    // 需要釋放存儲空間
}

這里需要注意的是,constexpr的使用可以進行編譯時期的計算。使用這一功能,我們可以這樣寫:

template <class T> void f(const T&);
f("Hello");    // 傳遞char*指針給f()
f("Hello"s);    // 傳遞(5個字符的)字符串對象給f()
f("Hello n"s);    // 傳遞(6個字符的)字符串對象給f()

auto z = 2+1i;    // 復數(shù)complex(2,1)

基本(實現(xiàn))方法是編譯器在解析什么語句代表一個變量之后,再分析一下后綴。用戶自定義數(shù)據(jù)標識機制只是簡簡單單的允許用戶制定一個新的后綴,并決定如何對它之前的數(shù)據(jù)進行處理。要想重新定義一個內(nèi)建的數(shù)據(jù)標識的意義或者它的參數(shù)、語法是不可能的。一個數(shù)據(jù)標識操作符可以使用它(前面)的數(shù)據(jù)標識傳遞過來的處理過的值(如果是使用新的沒有定義過的后綴的值)或者沒有處理過的值(作為一個字符串)。

要得到一個沒有處理過的字符串,只要使用一個單獨的const char*參數(shù)即可,例如:

Bignum operator"" x(const char* p)
{
    return Bignum(p);
}

void f(Bignum);
f(1234567890123456789012345678901234567890x);

這個C語言風格的字符串”1234567890123456789012345678901234567890″被傳遞給了操作符 operator”” x()。注意,我們并沒有明確地把數(shù)字轉(zhuǎn)換成字符串。

有以下四種數(shù)據(jù)標識的情況,可以被用戶定義后綴來使用用戶自定義數(shù)據(jù)標識:

  • 整型標識:允許傳入一個unsigned long long或者const char*參數(shù)
  • 浮點型標識:允許傳入一個long double或者const char*參數(shù)
  • 字符串標識:允許傳入一組(const char*,size_t)參數(shù)
  • 字符標識:允許傳入一個char參數(shù)。

根據(jù) C++ 11 標準,只有下面這些簽名是合法的:

char const*
unsigned long long
long double
char const, std::size_t
wchar_t const*, std::size_t
char16_t const*, std::size_t
char32_t const*, std::size_t

上面列出的第一個簽名不要同字符串相混淆,應該被稱為原始字面量 raw literal 操作符。例如:

char const* operator"" _r(char const* s)
{
    return s;
}

int main()
{
    std::cout << 12_r << '\n';
}

注意,你為字符串標識定義的標識操作符不能只帶有一個const char*參數(shù)(而沒有大小)。例如:

//警告,這個標識操作符并不能像預想的那樣子工作
string operator"" S(const char* p);  
"one two"S;    //錯誤,沒有適用的標識操作符

根本原因是如果我們想有一個“不同的字符串”,我們同時也想知道字符的個數(shù)。后綴可能比較短(例如,s是字符串的后綴,i是虛數(shù)的后綴,m是米的后綴,x是擴展類型的后綴),所以不同的用法很容易產(chǎn)生沖突,我們可以使用namespace(命名空間)來避免這些名字沖突:

namespace Numerics {
    // …
    class Bignum { /* … */ };
    namespace literals {
        operator"" X(char const*);
    }
}
using namespace Numerics::literals;

參考資料

C++11 用戶自定義字面值
C++11 新特性:用戶定義字面量
【c++11FAQ】用戶定義數(shù)據(jù)標識
cpp11新特性詳解與應用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容