中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

wordpress 禁止評論關(guān)鍵詞優(yōu)化顧問

wordpress 禁止評論,關(guān)鍵詞優(yōu)化顧問,開發(fā)者模式要不要開,做公司網(wǎng)站需要服務(wù)器嗎原文 C17基于結(jié)構(gòu)綁定的編譯期反射 事實上不需要宏的編譯期反射在C17中已用得很多了,比如struct_pack的編譯期反射就不需要宏,因為C17結(jié)構(gòu)綁定可直接得到一個聚集類的成員的引用. struct person {int id;std::string name;int age; }; int main() {person p{1, "tom&qu…

原文

C++17基于結(jié)構(gòu)綁定的編譯期反射

事實上不需要宏的編譯期反射C++17中已用得很多了,比如struct_pack編譯期反射就不需要宏,因為C++17結(jié)構(gòu)綁定可直接得到一個聚集類的成員的引用.

struct person {int id;std::string name;int age;
};
int main() {person p{1, "tom", 20};auto &[id, name, age] = p;std::cout << name << "\n";
}

沒有宏也沒有侵入式,一切都很完美,但是有兩個比較大的問題:

問題一
結(jié)構(gòu)綁定方式無法取字段名,這是一個主要問題,如果想序化對象到json,xml時,需要字段名時就無法滿足需求了.
問題二
除此外還有另外一個問題,如果一個對象有構(gòu)造器私有成員時,則它就不是一個聚集類型了,無法再用結(jié)構(gòu)綁定反射內(nèi)部的字段了.

基于結(jié)構(gòu)綁定的編譯期反射無法解決這兩個主要問題,導(dǎo)致用途不大.

yalantinglibs.reflection反射庫

yalantinglibs.reflection反射庫直面并解決了這兩個問題,提供了統(tǒng)一的編譯期反射方法,無論對象是否是聚集類型,無論對象是否有私有字段都可用統(tǒng)一的api編譯期反射得到其元信息.

來看看yalantinglibs.reflection如何反射一個聚集類型的:

struct simple {int color;int id;std::string str;int age;
};
using namespace ylt::reflection;
int main() {simple p{.color = 2, .id = 10, .str = "hello reflection", .age = 6};//取對象字段個數(shù)static_assert(members_count_v<simple> == 4);//取對象所有字段名 constexpr auto arr = member_names<simple>; //std::array<std::string_view, N> //根據(jù)字段索引取字段值 CHECK(std::get<3> == 6); //get age CHECK(std::get<2> == "hello reflection"); //get str //根據(jù)字段名取字段值auto& age2 = get<"age"_ylts>(p);CHECK(age2 == 6);//遍歷對象,得到字段值和字段名for_each(p, [](auto& field_value, auto field_name) {std::cout << field_value << ", " << field_name << "\n";});
}

yalantinglibs的編譯期反射相比前結(jié)構(gòu)綁定方式的反射更進(jìn)一步了,不僅是無宏非侵入式,還能得到字段名,這樣就把第一個問題解決掉了,可用在數(shù)格xml等需要字段名的場景下了.

yalantinglibs.reflection是如何完成非侵入式取得聚集對象的字段名的呢?因為reflectcpp這道光!

該庫的作者發(fā)現(xiàn)了一個新方法可在C++20高版本的編譯器中非侵入式的取得聚集對象的字段名.能發(fā)現(xiàn)該方法我只能說你真是個天才!

該方法說起來也不算復(fù)雜,分兩步實現(xiàn):
第一步:在編譯期取得對象字段值的指針;
第二步:在編譯期第一步得到的指針解析出字段名;
是不是很簡單,接著看看具體是如何實現(xiàn)的吧.

在編譯期取得對象字段值的指針

reflectcpp在實現(xiàn)這一步時做得比較復(fù)雜,yalantinglibs大幅簡化了這一步的實現(xiàn).

template <class T, std::size_t n>
struct object_tuple_view_helper {static constexpr auto tuple_view(){}
};
template <class T>
struct object_tuple_view_helper<T, 0> {static constexpr auto tuple_view() { return std::tie(); }
};
template <class T>
struct object_tuple_view_helper<T, 4> {static constexpr auto tuple_view() {auto& [a, b, c, d] = get_fake_object<remove_cvref_t<T>>();auto ref_tup = std::tie(a, b, c, d);auto get_ptrs = [](auto&... _refs) {return std::make_tuple(&_refs...);};return std::apply(get_ptrs, ref_tup);}
};

偏特化模板類object_tuple_view_helper,在tuple_view函數(shù)中,先結(jié)構(gòu)綁定得到字段值的引用,然后按指針轉(zhuǎn)換它,并放到元組中,來返回給用戶.

這里偏特化的關(guān)鍵在于n,它表示聚集對象字段的個數(shù),該字段個數(shù)是可在編譯期取的.為了避免針對不同字段個數(shù)聚集類型寫重復(fù)的偏特化的代碼,可用腳本生成這些代碼.

#define RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( \n, ...)                                                                         \template <class T>                                                                \struct object_tuple_view_helper<T, n> {                                           \static constexpr auto tuple_view() {                                            \auto& [__VA_ARGS__] = get_fake_object<remove_cvref_t<T>>();                   \auto ref_tup = std::tie(__VA_ARGS__);                                         \auto get_ptrs = [](auto&... _refs) {                                          \return std::make_tuple(&_refs...);                                          \};                                                                            \return std::apply(get_ptrs, ref_tup);                                         \}                                                                               \}
/*The following boilerplate code was generated using a Python script:
macro =
"RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS"
with open("generated_code4.cpp", "w", encoding="utf-8") as codefile:codefile.write("\n".join([f"{macro}({i}, {', '.join([f'f{j}' for j in range(i)])});"for i in range(1, 256)]))
*/
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS(1, f0);
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS(2, f0, f1);
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS(3, f0, f1, f2);
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( 4, f0, f1, f2, f3);
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( 5, f0, f1, f2, f3, f4);
RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( 6, f0, f1, f2, f3, f4, f5);
...

生成偏特化代碼后,就可簡單取得聚集對象字段的指針.

template <class T>
inline constexpr auto struct_to_tuple() {return object_tuple_view_helper<T, members_count_v<T>>::tuple_view();
}

調(diào)用struct_to_tuple就能在編譯期取得T所有字段的指針了,其中編譯期取T的字段個數(shù)的方法members_count_v就是來自于struct_pack中的方法,前面在介紹struct_pack的文章里已詳細(xì)講過,就不再贅述了.

根據(jù)字段指針取字段名

有了編譯期得到的字段指針后就很容易取其字段名了:

template <auto ptr>
inline constexpr std::string_view get_member_name() {
#if defined(_MSC_VER)constexpr std::string_view func_name = __FUNCSIG__;
#elseconstexpr std::string_view func_name = __PRETTY_FUNCTION__;
#endif
#if defined(__clang__)auto split = func_name.substr(0, func_name.size() - 2);return split.substr(split.find_last_of(":.") + 1);
#elif defined(__GNUC__)auto split = func_name.substr(0, func_name.rfind(")}"));return split.substr(split.find_last_of(":") + 1);
#elif defined(_MSC_VER)auto split = func_name.substr(0, func_name.rfind("}>"));return split.substr(split.rfind("->") + 2);
#elsestatic_assert(false,"You are using an unsupported compiler. Please use GCC, Clang ""or MSVC or switch to the rfl::Fieldsyntax.");
#endif
}

template<auto ptr>C++17的特性,可用來聲明一個非類型模板參數(shù),來避免寫具體類型.

有了該編譯期的后,剩下的就是根據(jù)編譯產(chǎn)生的符號去截取需要的部分串了,注意每個平臺生成的符號有差異,需要宏來區(qū)分各個平臺的截取方式.

為什么用指針可以取字段名?C++17或以下的編譯器是不是也可這樣來取呢?
第一個問題的答案是:reflectcpp作者發(fā)現(xiàn)的該方法,很黑客,但是工作!
第二個問題的答案是:不可以,該方法只在支持C++20gcc11,clang13,msvc2022以上編譯器中才有效!

所以該非侵入式取字段名的方法也是有約束的,不適合低版本的編譯器.

完整的取字段列表的實現(xiàn):

template <class T>
struct Wrapper {using Type = T;T v;
};
template <class T>
Wrapper(T) -> Wrapper<T>;
//針對clang.
template <class T>
inline constexpr auto wrap(const T& arg) noexcept {return Wrapper{arg};
}
template <typename T>
inline constexpr std::array<std::string_view, members_count_v<T>>
get_member_names() {constexpr auto tp = struct_to_tuple<T>();std::array<std::string_view, Count> arr;[&]<size_t... Is>(std::index_sequence<Is...>) mutable {((arr[Is] = get_member_name<wrap(std::get<Is>(tp))>()), ...);}(std::make_index_sequence<Count>{});return arr;
}

至此,兩步完成,可用get_member_names函數(shù)非侵入式的取得聚集對象的字段名列表了.

如何處理非聚集類型?

在高版本的編譯器中無宏非侵入式得到聚集對象字段名列表固然很好,但是非聚集類型要如何處理呢?如果編譯器版本不夠,只有C++17又該怎么辦?

yalantinglibs.reflection未來遠(yuǎn)不止你想象的,想能統(tǒng)一整個編譯期反射的內(nèi)容,無論對象是聚集還是非聚集,無論對象是否含有私有字段都提供統(tǒng)一的反射接口!

比如像這樣一個對象:

class private_struct {int a;int b;public:private_struct(int x, int y) : a(x), b(y) {}
};private_struct st(2, 4);ylt::reflection::refl_visit_members(st, [](auto&... args) {((std::cout << args << " "), ...);std::cout << "\n";});

private_struct是一個含私有字段非聚集類型,但是ylt::reflection也能反射它.但是這里還漏掉了一個宏,是,還是需要宏,在編譯期反射進(jìn)入到標(biāo)準(zhǔn)庫前,對非聚集類型仍需要的.

class private_struct {int a;int b;public:private_struct(int x, int y) : a(x), b(y) {}
};
YLT_REFL_PRIVATE(private_struct, a, b);

對沒有字段的非聚集類型來說,也適合C++17,可這樣定義宏:

struct dummy_t {int id;std::string name;int age;YLT_REFL(dummy_t, id, name, age);
};
struct dummy_t2 {int id;std::string name;int age;
};
YLT_REFL(dummy_t2, id, name, age);

總結(jié)

高版本的編譯器中可完全不使用宏,低版本或非聚集類型宏來實現(xiàn)編譯器反射,無論是聚集還是非聚集都是使用同一套反射接口,這樣可覆蓋所有要用編譯期反射的場景,這就是yalantinglibs.reflection提供的能力!

后面struct_pack,struct_pb,struct_json,struct_xml,struct_yaml都會使用yalantinglibs.reflection提供的統(tǒng)一的編譯期反射接口來實現(xiàn)序化和反序化.

http://www.risenshineclean.com/news/21663.html

相關(guān)文章:

  • 做網(wǎng)站需要注冊公司嗎今日新聞內(nèi)容摘抄
  • 建設(shè)政務(wù)門戶網(wǎng)站的基本意義網(wǎng)絡(luò)推廣的途徑有哪些
  • 無錫做網(wǎng)站價格搜索風(fēng)云排行榜
  • 記事本做網(wǎng)站怎么調(diào)整圖片間距seo優(yōu)化團(tuán)隊
  • 做網(wǎng)站切圖是什么意思百度關(guān)鍵詞推廣費用
  • 企業(yè)網(wǎng)站建設(shè)的一般原則國外網(wǎng)站如何搭建網(wǎng)頁
  • 源代碼建網(wǎng)站百度seo2022新算法更新
  • 泰州網(wǎng)站建設(shè)服務(wù)熱線國際實時新聞
  • wordpress后臺504seo查詢工具
  • 怎樣優(yōu)化網(wǎng)站渠道推廣有哪些方式
  • 福建省建設(shè)執(zhí)業(yè)注冊中心網(wǎng)站沈陽黃頁88企業(yè)名錄
  • 愛愛做網(wǎng)站開源crm系統(tǒng)
  • 網(wǎng)頁首站免費刷贊網(wǎng)站推廣qq免費
  • 網(wǎng)站排名查詢工具有哪些北京推廣優(yōu)化經(jīng)理
  • 華為網(wǎng)站建設(shè)官網(wǎng)杭州網(wǎng)站優(yōu)化推薦
  • 網(wǎng)站主頁的要素衡水seo培訓(xùn)
  • 佛山做網(wǎng)站那家好windows優(yōu)化大師是電腦自帶的嗎
  • 南通做網(wǎng)站企業(yè)qq群排名優(yōu)化軟件
  • 網(wǎng)站怎么做透明導(dǎo)航優(yōu)化大師官網(wǎng)入口
  • 重慶沙坪壩有哪些大學(xué)班級優(yōu)化大師是干什么用的
  • 用vs2013做網(wǎng)站案例百度高級搜索入口
  • 淘寶網(wǎng)網(wǎng)站設(shè)計分析黃岡seo
  • 彩票網(wǎng)站里的統(tǒng)計怎么做如何在手機(jī)上開自己的網(wǎng)站
  • 招商網(wǎng)站建設(shè)多少錢合肥seo報價
  • wordpress驗證google站長營銷策劃公司取名大全
  • 鄂爾多斯市東勝區(qū)城市建設(shè)局網(wǎng)站網(wǎng)站新域名查詢
  • 畢業(yè)設(shè)計指導(dǎo)網(wǎng)站開發(fā)企業(yè)如何做網(wǎng)絡(luò)推廣
  • 做動畫相冊在哪個網(wǎng)站好百度游戲中心
  • 怎么做網(wǎng)站用于推廣seo排名優(yōu)化推廣報價
  • 培訓(xùn)機(jī)構(gòu)退費糾紛一般怎么解決關(guān)于進(jìn)一步優(yōu)化落實疫情防控措施