Share
Embed
Transcript
45 slides
-
std::conjuncion std::conjuncion B...の論理積を⾏うメタ関数。 ⼀般にはメタ述語AとB(あるいはもっとたくさん)のすべてを満たすか 判定したい場合などに使うはず。 namespacestd{ template<class...B> structconjunction; template<class...B>
inlineconstexprbool conjunction_v=conjunction<B...>::value; } -
std::conjuncion std::conjuncion indetail indetail テンプレート引数が空のとき、std::true_typeを基底クラスに持つ というテンプレート引数を持つとき、 がはじ めてfalseになる型を基底クラスに持つ がtrueのとき、 を基底クラスに持つ
B , ..., B 1 n bool(B : i : value) B : n−1 : value B n -
std::conjuncion std::conjuncion Tips Tips がはじめてfalseとなるとき であるような はそもそもvalueを持たなくて良い B : i
: value j > i Bj static_assert( std::conjunction_v<std::false_type, std::nullptr_t> ==false);//OK -
std::disjuncion std::disjuncion B...の論理和を⾏うメタ関数。 ⼀般にはメタ述語AとB(あるいはもっとたくさん)のどれかを満たすか 判定したい場合などに使うはず。 namespacestd{ template<class...B> structdisjuncion; template<class...B>
inlineconstexprbool disjuncion_v=disjuncion<B...>::value; } -
std::disjunction std::disjunction example example いい例が思いつかない、つらい・・・ 型Tのデフォルト値をなんやかんやする例。 template<classT> inlinestd::enable_if_t<std::disjunction_v< std::is_default_constructible<T>, std::is_aggregate<T>>,T>
default_v=[]{ ifconstexpr(std::is_aggregate_v<T>){returnT{};} else{returnT();} }(); -
std::disjunction std::disjunction indetail indetail テンプレート引数が空のとき、std::false_typeを基底クラスに持つ というテンプレート引数を持つとき、 がはじ めてtrueになる型を基底クラスに持つ がfalseのとき、 を基底クラスに持つ
B , ..., B 1 n bool(B : i : value) B : n−1 : value B n -
std::disjunction std::disjunction Tips Tips がはじめてtrueとなるとき であるような はそもそもvalueを持たなくて良い B : i
: value j > i Bj static_assert( std::disjunction_v<std::true_type, std::nullptr_t> ==true);//OK -
std::negation std::negation あるメタ述語Bの論理否定を⾏うメタ関数。 std::bool_constant<!bool(B::value)>を基底クラスに持つ。 メタ述語の否定のメタ述語を作りたいときに。 namespacestd{ template<classB> structnegation:bool_constant<!bool(B::value)>{}; template<classB>
inlineconstexprbool negation_v=negation<B...>::value; } -
std::negation std::negation example example std::conjunction,std::disjunctionのパラメータパック内でメタ述語 の否定をしたいときに使うのは想定されるよね。 メタ述語でなくいいなら!std::is_integral_v<Ts>...と書ける。 template<typename...Ts> std::enable_if_t<std::conjunction_v< std::negation<std::is_integral<Ts>>...>>
func(Ts...xs){//Ts...はすべて整数ではない型 //... } -
is_swappableの⼀族 is_swappableの⼀族 規格書のTable42—Typepropertypredicatesでひときわ⻑い説明が書い てあるので印象深い。 template<classT,classU> structis_swappable_with; template<classT> structis_swappable;
template<classT,classU> structis_nothrow_swappable_with; template<classT> structis_nothrow_swappable; -
is_swappable_with<T,U> is_swappable_with<T,U> usingstd::swap usingstd::swapされたという条件下かつ、 されたという条件下かつ、 未評価な⽂脈で 未評価な⽂脈で swap(declval<T>(),declval<U>()) swap(declval<T>(),declval<U>())と と
swap(declval<U>(),declval<T>()) swap(declval<U>(),declval<T>())が が ともにwell-formedな式となるかを判定する。 ともにwell-formedな式となるかを判定する。 Preconditions 型TとUが、完全型であること。 もしくは(cv修飾された)voidか、要素数不明の配列型であること。 -
§23.15.4.3Type §23.15.4.3Type properties/C++17 properties/C++17 inTable42—Typepropertypredicates inTable42—Typepropertypredicates AccesscheckingisperformedasifinacontextunrelatedtoTandU. Onlythevalidityoftheimmediatecontextoftheswapexpressionsis considered. [Note:Thecompilationoftheexpressionscanresultinsideeffectssuch
astheinstantiationofclasstemplatespecializationsandfunction templatespecializations,thegenerationofimplicitly-definedfunctions, andsoon.Suchsideeffectsarenotinthe immediatecontext andcan resultintheprogrambeingill-formed.—endnote] -
SFINAE-friendlyでないメタ関数 SFINAE-friendlyでないメタ関数 #include<utility> template<typenameT1,typenameT2> structPlusResultT{ usingType =decltype(std::declval<T1>() +std::declval<T2>()); };
template<typenameT1,typenameT2> usingPlusResult =typenamePlusResultT<T1,T2>::Type; -
SFINAE-friendlyなメタ関数 SFINAE-friendlyなメタ関数 #include<utility> //primarytemplate: template<typename,typename, typename=std::void_t<>> structHasPlusT:std::false_type {}; //partialspecialization(maybeSFINAE
daway): template<typenameT1,typenameT2> structHasPlusT<T1,T2, std::void_t<decltype(std::declval<T1>() +std::declval<T2>())>> :std::true_type {}; -
SFINAE-friendlyなメタ関数 SFINAE-friendlyなメタ関数 #include<utility> //primarytemplate, //usedwhenHasPlusTyieldstrue template<typenameT1,typenameT2, bool=HasPlusT<T1,T2>::value> structPlusResultT{ usingType=decltype(std::declval<T1>() +std::declval<T2>());
}; //partialspecialization,usedotherwise template<typenameT1,typenameT2> structPlusResultT<T1,T2,false>{}; -
参考⽂献 参考⽂献 ISO/IEC148822017 C++Templates:TheCompleteGuide-SecondEdition workingdraft http://eel.is/c++draft/dcl.init.aggr Adding[nothrow-]swappabletraits,revision3 http://www.open- std.org/jtc1/sc22/wg21/docs/papers/2016/p0185r1.html Stackoverlow:Whyisswappingmultidimensionalarraysnotnoexcept?
https://stackoverflow.com/questions/26793979/why-is-swapping- multidimensional-arrays-not-noexcept