diff options
author | johannst <johannst@users.noreply.github.com> | 2023-04-12 20:57:45 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2023-04-12 20:57:45 +0000 |
commit | 4b3a334cf553b9f0b7f831538cb4d23fbdb0594f (patch) | |
tree | 3a8e4df94497b437656454bc29e522b56f9765cb /print.html | |
parent | 3f1d25c3e62f91f2555f0649c7c71f3b730717be (diff) | |
download | notes-4b3a334cf553b9f0b7f831538cb4d23fbdb0594f.tar.gz notes-4b3a334cf553b9f0b7f831538cb4d23fbdb0594f.zip |
deploy: d6deac54dd372c946942637636846893694ce521
Diffstat (limited to 'print.html')
-rw-r--r-- | print.html | 129 |
1 files changed, 121 insertions, 8 deletions
@@ -33,6 +33,7 @@ </head> <body> + <div id="body-container"> <!-- Provide site root to javascript --> <script> var path_to_root = ""; @@ -70,10 +71,12 @@ <!-- Hide / unhide sidebar before it is displayed --> <script> var html = document.querySelector('html'); - var sidebar = 'hidden'; + var sidebar = null; if (document.body.clientWidth >= 1080) { try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } sidebar = sidebar || 'visible'; + } else { + sidebar = 'hidden'; } html.classList.remove('sidebar-visible'); html.classList.add("sidebar-" + sidebar); @@ -2922,8 +2925,7 @@ struct is_entry { template<typename TT> using val = decltype(std::declval<TT>().val()); - static constexpr bool value = is_valid_v<T, init> && - is_valid_with_ret_v<T, int, tag> && + static constexpr bool value = is_valid_v<T, init> && is_valid_with_ret_v<T, int, tag> && is_valid_with_ret_v<T, typename T::Type, val>; }; @@ -2946,18 +2948,128 @@ int main() { of the <code>decltype(std:declval<T>...</code> expressions is ill-formed, the template specialization for <code>is_valid</code> will be removed from the candidate set due to <a href="https://en.cppreference.com/w/cpp/language/sfinae">SFINAE</a>.</p> -<pre><code class="language-cpp">template<typename T, typename = void> +<pre><code class="language-cpp">#include <type_traits> + +// (1) Primary template. +template<typename T, typename = void> struct is_valid : std::false_type {}; +// (2) Partial template specialization. template<typename T> -struct is_valid<T, std::void_t< - decltype(std::declval<T>().some_fun1()), - decltype(std::declval<T>().some_fun2()) - >> : std::true_type {}; +struct is_valid<T, std::void_t<decltype(std::declval<T>().some_fun1()), + decltype(std::declval<T>().some_fun2())>> : std::true_type {}; +struct A { + void some_fun1() {} + void some_fun2() {} +}; + +struct B {}; + +static_assert(is_valid<A>::value, "is true"); +// * Compare template arg list with primary template, we only supplied one +// arg, the second one will be defaulted as +// is_valid<A, void> +// * Compare template arg list against available specializations, this will +// try to match the pattern <A, void> against the patterns defined in the +// partial specializations. +// * Try specialization (2) +// * T -> A +// * Evaluate std::void_t -> decltype's are well-formed +// std::void_t<...> -> void +// * Specialization (2) matches <A, void> +// * Pick the most specialized version -> (2) + +static_assert(!is_valid<B>::value, "is false"); +// * Compare template arg list with primary template, we only supplied one +// arg, the second one will be defaulted as +// is_valid<A, void> +// * Compare template arg list against available specializations, this will +// try to match the pattern <B, void> against the patterns defined in the +// partial specializations. +// * Try specialization (2) +// * T -> B +// * Evaluate std::void_t -> decltype's are ill-formed +// * Specialization (2) is removed from candidate set, no hard error (SFINAE) +// * No specialization matches, take the primary template. </code></pre> <blockquote> <p><code>std::declval<T>()</code> creates an instance of type T in an unevaluated context.</p> </blockquote> +<p>A more detailed description is available in the SO discussion <a href="https://stackoverflow.com/a/27688405">How does +<code>void_t</code> work</a>.</p> +<h2 id="template-selection-with-partially--fully-specializations"><a class="header" href="#template-selection-with-partially--fully-specializations">Template selection with partially / fully specializations.</a></h2> +<pre><code class="language-cpp">enum Kind { + kPrimary, + kTT, + kIntBool, + kIntInt, +}; + +// (1) Primary template. +template<typename T, typename U = bool> +struct pair { + static constexpr Kind kind = kPrimary; +}; + +// (2) Partial template specialization. +template<typename T> +struct pair<T, T> { + static constexpr Kind kind = kTT; +}; + +// (3) Template specialization. +template<> +struct pair<int, bool> { + static constexpr Kind kind = kIntBool; +}; + +// (4) Template specialization. +template<> +struct pair<int, int> { + static constexpr Kind kind = kIntInt; +}; + +int main() { + static_assert(pair<int>::kind == kIntBool, ""); + // * Compare template arg list with primary template, we only supplied one + // arg, the second one will be defaulted as + // pair<int, bool> + // * Compare template arg list against available specializations, this will + // try to match the pattern <int, bool> against the patterns defined in the + // partial specializations. + // * (2) <int, bool> pattern does not match + // * (3) <int, bool> pattern does match + // * (4) <int, bool> pattern does not match + // * Pick the most specialized version -> (3) + + static_assert(pair<char, char>::kind == kTT, ""); + // * Compare template arg list against available specializations, this will + // try to match the pattern <char, char> against the patterns defined in the + // partial specializations. + // * (2) <char, char> pattern does match + // * (3) <char, char> pattern does not match + // * (4) <char, char> pattern does not match + // * Pick the most specialized version -> (2) + + static_assert(pair<int, int>::kind == kIntInt, ""); + // * Compare template arg list against available specializations, this will + // try to match the pattern <int, int> against the patterns defined in the + // partial specializations. + // * (2) <int, int> pattern does match + // * (3) <int, int> pattern does match + // * (4) <int, int> pattern does not match + // * Pick the most specialized version -> (3) + + static_assert(pair<char, short>::kind == kPrimary, ""); + // * Compare template arg list against available specializations, this will + // try to match the pattern <char, short> against the patterns defined in the + // partial specializations. + // * (2) <char, short> pattern does not match + // * (3) <char, short> pattern does not match + // * (4) <char, short> pattern does not match + // * No specialization matches, take the primary template. +} +</code></pre> <div style="break-before: page; page-break-before: always;"></div><h1 id="glibc"><a class="header" href="#glibc">glibc</a></h1> <h2 id="malloc-tracer-mtrace3"><a class="header" href="#malloc-tracer-mtrace3">malloc tracer <a href="http://man7.org/linux/man-pages/man3/mtrace.3.html"><code>mtrace(3)</code></a></a></h2> <p>Trace memory allocation and de-allocation to detect memory leaks. @@ -5209,5 +5321,6 @@ required when compiling natively on riscv.</p> }); </script> + </div> </body> </html> |