我經常在大型代碼庫中遇到不遵循 typedef 標準約定的代碼,ThisType例如this_type.
在我不再依賴的地方撰寫通用代碼this_type意味著我必須為每種沒有的型別提供一些腳手架代碼this_type.
我想兩者this_type和ThisType可以定義。但是,在大型代碼庫中會增加額外的噪音,并且需要定期檢查。
有沒有辦法把它包裝成type_trait這樣我可以寫一些類似的東西:this_type<SomeType>::value_type 或者其他一些通用的解決方案?
uj5u.com熱心網友回復:
也許可以以更簡單的方式完成……無論如何,我提出了一個標簽調度/SFINAE 解決方案。
首先,一個簡單的遞回tag結構
template <std::size_t N>
struct tag : public tag<N-1u>
{ };
template <>
struct tag<0u>
{ };
以避免在定義更多可能的型別名稱的情況下產生歧義。
然后為您想要從可能的型別中提取的每種型別提供一個模板函式(僅宣告);一個為type
template <typename T, std::void_t<typename T::type>* = nullptr>
typename T::type getType (tag<0u>);
一個為this_type
template <typename T, std::void_t<typename T::this_type>* = nullptr>
typename T::this_type getType (tag<1u>);
一個為ThisType
template <typename T, std::void_t<typename T::ThisType>* = nullptr>
typename T::ThisType getType (tag<2u>);
還有一個(有點傻)MySillyTypeName
template <typename T, std::void_t<typename T::MySillyTypeName>* = nullptr>
typename T::MySillyTypeName getType (tag<3u>);
觀察到的數量tag是不同的:這避免了可能的歧義,并為名稱提供了優先順序。
現在是一個getType()用于提取所需型別的簡單結構
template <typename T, typename U = decltype(getType<T>(tag<100u>()))>
struct GetType { using type = U; };
The following is a full compiling C 17 example
#include <type_traits>
template <std::size_t N>
struct tag : public tag<N-1u>
{ };
template <>
struct tag<0u>
{ };
template <typename T, std::void_t<typename T::type>* = nullptr>
typename T::type getType (tag<0u>);
template <typename T, std::void_t<typename T::this_type>* = nullptr>
typename T::this_type getType (tag<1u>);
template <typename T, std::void_t<typename T::ThisType>* = nullptr>
typename T::ThisType getType (tag<2u>);
template <typename T, std::void_t<typename T::MySillyTypeName>* = nullptr>
typename T::MySillyTypeName getType (tag<3u>);
template <typename T, typename U = decltype(getType<T>(tag<100u>()))>
struct GetType { using type = U; };
struct foo1 { using type = short; };
struct foo2 { using this_type = int; };
struct foo3 { using ThisType = long; };
struct foo4 { using MySillyTypeName = long long; };
int main()
{
static_assert( std::is_same_v<short, GetType<foo1>::type> );
static_assert( std::is_same_v<int, GetType<foo2>::type> );
static_assert( std::is_same_v<long, GetType<foo3>::type> );
static_assert( std::is_same_v<long long, GetType<foo4>::type> );
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/438905.html
上一篇:C -將模板類的指標傳遞給函式
