巧用enum來獲取std tuple中的元素

2021-07-09 01:45:38 字數 1795 閱讀 2522

今天看scott meyers的《effective modern c++》的item 10: prefer scoped enums to unscoped enums 。他建議我們在獲取std::tuple中的元素時(利用std::get()),可以用unscoped enums來代替索引值index,這樣可以增強程式的可讀性,原例如下:

using userinfo =

std:

:tuple:

:string, // name

std:

:string, // email

std:

:size_t> ;// reputation

userinfo uinfo; // object of tuple type

...auto val = std:

:get<

1>(uinfo); // get value of field 1

enum userinfofields ;

auto val = std:

:get(uinfo); // ah, get value of email field

上面的例子中,get顯然要比get<1>看起來更加清楚。尤其當我們的tuple中有較多個元素時,如果每次取某個元素時都要從頭開始數,想必是很痛苦的。

利用unscoped enum則看起來方便了許多,這種方法利用了unscoped enum的幾個特性:

但是, unscoped enum的缺點之一就是所謂的namespace pollution(命名空間汙染),它會把enum中元素的作用域擴大到enum自己所在的作用域,而不是把它們限定在enum之中。這樣,在enum所在的作用域,其元素的名字就好像乙個全域性變數一樣。在此作用域內,不能再定義同名變數了。

個人認為這樣做不太合理,最好是讓unscoped enum像scoped enum(enum class)那樣,將其元素的作用域限定在enum中,這樣**閱讀起來更加清晰,也更加安全一些。我想到的實現方式是用namespace把unscoped enum的定義式括起來,如下所示:

#include 

#include

#include

#include

#define print_it(***) (std::cout << boost::format("%-20s = %d\n") % (#***) % (***) )

using person = std::tuple;

// 用namespace限定enum中元素的作用域

// enum中的各元素可看作person中對應元素的別名

namespace info;

}int main(int argc, char

const *argv) ;

//通過enum的隱式轉換來獲取tuple中的相應元素

auto name = std::get(mn);// 等價於std::get<0>(mn)

auto age = std::get(mn);// 等價於std::get<1>(mn)

auto height = std::get(mn);// 等價於std::get<2>(mn)

print_it(name);

print_it(age);

print_it(height);

return

0;}

這樣,我們在獲取tuple的元素時,**看起來更加直觀,也更加安全。

開發中巧用Enum列舉型別

在實際開發中,在資料庫表設計中,我們往往習慣於用乙個int型別的state欄位去表示資料的狀態,這個欄位很方便去表示這條資料的狀態,但是又不願意去建一張這個state欄位的外來鍵表去解釋狀態。我們一般會把這個state欄位當成乙個約定,去在專案中應用 比如 0 啟用,1 禁用 在後台管理或其它地方顯...

巧用FireFox來除錯Silverlight

做前端開發的朋友應該對firefox再熟悉不過了,firefox有乙個附加元件firebug。在html中可以直接寫 這樣在底部的控制台就能直接看到輸出的值,他的作用就好像visual studio中的console.writeline 一樣。我們在silverlight中就可以直接呼叫這個js方法...

使用列舉enum來代替if else

在平時的 中,if else肯定是必不可少,但是有時使用if else卻不是 的最好選擇,下面介紹下平時會在實際工作 中使用到的用enum來代替if else的寫法.現在有個需求,我們公司有vip等級,1,2,3,根據等級高低,能獲取不同的優惠資訊,最簡單也最容易想到的 是 獲取折扣資訊 publi...