<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[A little template challenge]]></title><description><![CDATA[<p>Ich arbeite gerade an Metafunktorkomposition. Wobei ich ein Funktor wie folgt definiere:</p>
<pre><code>struct Functor {
    template &lt;typename...&gt;
    struct apply {
        using type = *;
    };
};
</code></pre>
<p>Meine aktuelle Syntax ist die Folgende:</p>
<pre><code>using newFunctor = compose &lt;mul /* mul = ein functor der 2 Argumente akzeptiert */,
    compose &lt;add, mplex::placeholders::_1, int_ &lt;7&gt; &gt;,
    compose &lt;div, mplex::placeholders::_3, mplex::placeholders::_4&gt;
&gt;;

using result = newFunctor::template apply &lt;int_ &lt;1&gt;, int_ &lt;3&gt;, int_&lt;4&gt;&gt;;
</code></pre>
<p>mit</p>
<pre><code>template &lt;unsigned V&gt;
struct _ { // darf völlig geändert werden.
    constexpr static const unsigned value = V;
};

#define PLACEHOLDER_SHORT_HAND(NUM) \
using _ ## NUM = _&lt;NUM&gt;

PLACEHOLDER_SHORT_HAND(1);
</code></pre>
<p>Die Implementierung von compose habe ich noch nicht fertig, und bevor ich weiter mache, suche ich lieber:</p>
<ol>
<li>
<p><strong>Eine möglicherweise bessere Syntax</strong> für die Komposition. Die aktuelle gefällt mir schon eigentlich ganz gut, aber Vorschläge sind willkommen</p>
</li>
<li>
<p>Ein mögliche <strong>effiziente Implementierung</strong>. Effizient definiere ich fast ausschließlich über Instantiierungstiefe.</p>
</li>
</ol>
<p>Boost MPL ist erlaubt, das kann ich umübersetzen.</p>
<p>Vielleicht hat jemand Interesse sich darüber Gedanken zu machen. Ist eben nicht so eine &quot;normale&quot; Frage wie (Ich will XY, wie mach ich das?)</p>
<p>EDIT:<br />
bind ist übrigens schon fertig und funktioniert so ähnlich, nur nicht rekursiv und lazy.</p>
<pre><code>using doublify = bind &lt;mul, int_ &lt;2&gt;, _1&gt;; 
std::cout &lt;&lt; doublify &lt;int_&lt;4&gt;&gt;; // -&gt; 8
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/333842/a-little-template-challenge</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 08:58:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/333842.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 04 Aug 2015 13:27:02 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 13:34:30 GMT]]></title><description><![CDATA[<p>Ich arbeite gerade an Metafunktorkomposition. Wobei ich ein Funktor wie folgt definiere:</p>
<pre><code>struct Functor {
    template &lt;typename...&gt;
    struct apply {
        using type = *;
    };
};
</code></pre>
<p>Meine aktuelle Syntax ist die Folgende:</p>
<pre><code>using newFunctor = compose &lt;mul /* mul = ein functor der 2 Argumente akzeptiert */,
    compose &lt;add, mplex::placeholders::_1, int_ &lt;7&gt; &gt;,
    compose &lt;div, mplex::placeholders::_3, mplex::placeholders::_4&gt;
&gt;;

using result = newFunctor::template apply &lt;int_ &lt;1&gt;, int_ &lt;3&gt;, int_&lt;4&gt;&gt;;
</code></pre>
<p>mit</p>
<pre><code>template &lt;unsigned V&gt;
struct _ { // darf völlig geändert werden.
    constexpr static const unsigned value = V;
};

#define PLACEHOLDER_SHORT_HAND(NUM) \
using _ ## NUM = _&lt;NUM&gt;

PLACEHOLDER_SHORT_HAND(1);
</code></pre>
<p>Die Implementierung von compose habe ich noch nicht fertig, und bevor ich weiter mache, suche ich lieber:</p>
<ol>
<li>
<p><strong>Eine möglicherweise bessere Syntax</strong> für die Komposition. Die aktuelle gefällt mir schon eigentlich ganz gut, aber Vorschläge sind willkommen</p>
</li>
<li>
<p>Ein mögliche <strong>effiziente Implementierung</strong>. Effizient definiere ich fast ausschließlich über Instantiierungstiefe.</p>
</li>
</ol>
<p>Boost MPL ist erlaubt, das kann ich umübersetzen.</p>
<p>Vielleicht hat jemand Interesse sich darüber Gedanken zu machen. Ist eben nicht so eine &quot;normale&quot; Frage wie (Ich will XY, wie mach ich das?)</p>
<p>EDIT:<br />
bind ist übrigens schon fertig und funktioniert so ähnlich, nur nicht rekursiv und lazy.</p>
<pre><code>using doublify = bind &lt;mul, int_ &lt;2&gt;, _1&gt;; 
std::cout &lt;&lt; doublify &lt;int_&lt;4&gt;&gt;; // -&gt; 8
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2462416</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462416</guid><dc:creator><![CDATA[5cript]]></dc:creator><pubDate>Tue, 04 Aug 2015 13:34:30 GMT</pubDate></item><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 15:27:11 GMT]]></title><description><![CDATA[<p>Was ist mit folgender Syntax?</p>
<pre><code class="language-cpp">using newFunctor = decltype((_1 + int_&lt;7&gt;())*(_2/_3))::type;
auto constexpr result = eval(newFunctor{}, std::make_tuple(1, 6, 3));
static_assert(result == (1+7)*(6/3), &quot;&quot;);
</code></pre>
<p><code>result</code> wird zur Compilezeit berechnet, da es <code>constexpr</code> ist. Es ist auch möglich, <code>newFunctor</code> mit Klassen zu verwenden, die nicht in ein Template reinpassen, wie z.B. double:</p>
<pre><code class="language-cpp">auto constexpr result = eval(newFunctor{}, std::make_tuple(1.0, 1, 7.0));
</code></pre>
<p>Das geht mit deinem System nicht.</p>
<p><a href="https://ideone.com/mYQYxV" rel="nofollow">Code</a> (ist zwar C++14, sollte aber relativ leicht in C++11 übersetzbar sein):</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;
#include &lt;tuple&gt;

namespace mplex {

template &lt;std::size_t N&gt; struct placeholder {
  static constexpr std::size_t value = N;

  template &lt;typename T&gt;
  friend auto constexpr eval(placeholder, T&amp;&amp; tuple) { return std::get&lt;N&gt;(std::forward&lt;T&gt;(tuple)); }
};
using p1 = placeholder&lt;0&gt;;
using p2 = placeholder&lt;1&gt;;
using p3 = placeholder&lt;2&gt;;

template &lt;typename T&gt; struct expression_template { using type = T; };

auto _1 = expression_template&lt;p1&gt;{};
auto _2 = expression_template&lt;p2&gt;{};
auto _3 = expression_template&lt;p3&gt;{};

template &lt;int Value&gt;
expression_template&lt;std::integral_constant&lt;int, Value&gt; &gt; int_();

template &lt;typename T, T Value, typename X&gt;
auto constexpr eval(std::integral_constant&lt;T, Value&gt;, X&amp;&amp;) { return Value; }

template &lt;typename L, typename R&gt;
struct mul {
  template &lt;typename T&gt;
  friend auto constexpr eval(mul, T&amp;&amp; tuple) { return eval(L{}, tuple)*eval(R{}, tuple); }
};
template &lt;typename A, typename B&gt;
auto operator*(expression_template&lt;A&gt;, expression_template&lt;B&gt;) -&gt; expression_template&lt;mul&lt;A, B&gt;&gt;;

template &lt;typename L, typename R&gt;
struct add {
  template &lt;typename T&gt;
  friend auto constexpr eval(add, T&amp;&amp; tuple) { return eval(L{}, tuple)+eval(R{}, tuple); }
};
template &lt;typename A, typename B&gt;
auto operator+(expression_template&lt;A&gt;, expression_template&lt;B&gt;) -&gt; expression_template&lt;add&lt;A, B&gt;&gt;;

template &lt;typename L, typename R&gt;
struct div {
  template &lt;typename T&gt;
  friend constexpr auto eval(div, T&amp;&amp; tuple) { return eval(L{}, tuple)/eval(R{}, tuple); }
};
template &lt;typename A, typename B&gt;
auto operator/(expression_template&lt;A&gt;, expression_template&lt;B&gt;) -&gt; expression_template&lt;div&lt;A, B&gt;&gt;;

} // namespace mplex

int main()
{
  using namespace mplex;
  using newFunctor = decltype((_1 + int_&lt;7&gt;())*(_2/_3))::type;
  auto constexpr result = eval(newFunctor{}, std::make_tuple(1, 6, 3));
  static_assert(result == (1+7)*(6/3), &quot;&quot;);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2462430</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462430</guid><dc:creator><![CDATA[syntactico]]></dc:creator><pubDate>Tue, 04 Aug 2015 15:27:11 GMT</pubDate></item><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 15:32:20 GMT]]></title><description><![CDATA[<p>Die Syntax lässt sich noch weiter verfeinern:</p>
<pre><code class="language-cpp">template &lt;typename T, typename... Args&gt;
auto constexpr apply(Args&amp;&amp;... args) {
  return eval(typename T::type{}, std::make_tuple(std::forward&lt;Args&gt;(args)...));
}

// und dann:
using newFunctor = decltype((_1 + int_&lt;7&gt;())*(_2/_3));
auto constexpr result = apply&lt;newFunctor&gt;(1.0, 1, 7.0);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2462431</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462431</guid><dc:creator><![CDATA[syntactico]]></dc:creator><pubDate>Tue, 04 Aug 2015 15:32:20 GMT</pubDate></item><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 15:47:09 GMT]]></title><description><![CDATA[<p>Ich würde vorschlagen, statt diesem <code>struct _</code> Hack user-defined literals zu verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2462434</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462434</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Tue, 04 Aug 2015 15:47:09 GMT</pubDate></item><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 15:49:52 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Ich würde vorschlagen, statt diesem <code>struct _</code> Hack user-defined literals zu verwenden.</p>
</blockquote>
<p>+1<br />
Dann sind wir bei</p>
<pre><code class="language-cpp">decltype((_1 + 7_ce)*(_2/_3));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2462436</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462436</guid><dc:creator><![CDATA[syntactico]]></dc:creator><pubDate>Tue, 04 Aug 2015 15:49:52 GMT</pubDate></item><item><title><![CDATA[Reply to A little template challenge on Tue, 04 Aug 2015 16:19:09 GMT]]></title><description><![CDATA[<p>Grundsätzlich erstmal: Mir gefällt wie es funktioniert und es erinnert mich an boost lambda.<br />
Die ganze Sache müsste aber auf Typen operieren, nicht auf Werten und mehr als alle Operatoren verstehen.</p>
<p>Jetzt habe ich zum Beispiel Haufen structs die gewissen Kram machen, zum Beispiel im Einsatz als Predikate in Metafunktionen (also als Template Argumente)</p>
<p>Wieder sehen die so aus (oder ähnlich | Parameteranzahl variadisch):</p>
<pre><code>struct someFunctionality {
    template &lt;typename T, typename U, typename W&gt;
    struct apply { using type = result; /* whatever*/ };
};
</code></pre>
<p>Das ist ein wiederkehrendes Muster.</p>
<p>Der &quot;Nutzer&quot; könnten nun weiter Funktoren gleicher Art hinzufügen.<br />
Welche dann zusammengesetzten werden können sollen.<br />
Am besten so, dass man die nicht alle anpassen muss oder einen Haufen &quot;Peripheriecode&quot; schreiben, damit sie &quot;verstanden&quot; werden. (Außer vllt mit Macros, oder Vererbung).</p>
<p><strong>Vorausgesetzt ich habe dein Code lang genug angesehen und ausreichend verstanden.</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2462441</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2462441</guid><dc:creator><![CDATA[5cript]]></dc:creator><pubDate>Tue, 04 Aug 2015 16:19:09 GMT</pubDate></item></channel></rss>