<?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[decltype mit unbekannten Parametern als Parameter]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich will einen Minimierungs-Algorithmus schreiben. Dabei habe ich folgendes Problem:</p>
<pre><code>template &lt;typename T&gt;
struct min_options
{
	T tolerance; // Ein paar Optionen
};

template &lt;typename cost_function&gt;
void minimize(cost_function &amp;function_, min_options&lt;decltype(function_(/* Problem */))&gt; const &amp;opts)
{
	// Hier Implementierung
}

double my_cost_function(std::vector&lt;double&gt;::iterator begin_, std::vector&lt;double&gt;::iterator end_)
{
	return 1.0; // Nur ein Beispiel
}

int main()
{
	min_options&lt;double&gt; my_options;
	my_options.tolerance = 1.0e-9; // Toleranz festlegen

	minimize(my_cost_function, my_options); // Minimiere &quot;my_cost_function&quot; mit optionen &quot;my_options&quot;

}
</code></pre>
<p>Die Funktion minimize soll ein Optionen-struct mitübergeben bekommen. Dieses soll sich korrekt selbst instanziieren, und zwar in Abhängigkeit des Rückgabewertes der übergebenen Kostenfunktion (hier: my_cost_function). Da in diesem Beispiel die Kostenfunktion double zurückgibt, soll der Aufruf von minimize double als template Parameter für das struct verwenden.</p>
<p>Problem ist jetzt dass ich um decltype zu verwenden ja die genaue Funktionssignatur mit deren Typen kennen müsste (hier: std::vector&lt;double&gt;::iterator). Daher meine Frage, kann man sich nicht irgendwie einfach nur den Rückgabe-Typen einer Funktion holen, ohne dessen Funktionssignatur kennen zu müssen (wie bei decltype nötig)?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/327832/decltype-mit-unbekannten-parametern-als-parameter</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Jul 2026 17:37:56 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/327832.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 06 Sep 2014 18:19:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Sat, 06 Sep 2014 18:21:36 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich will einen Minimierungs-Algorithmus schreiben. Dabei habe ich folgendes Problem:</p>
<pre><code>template &lt;typename T&gt;
struct min_options
{
	T tolerance; // Ein paar Optionen
};

template &lt;typename cost_function&gt;
void minimize(cost_function &amp;function_, min_options&lt;decltype(function_(/* Problem */))&gt; const &amp;opts)
{
	// Hier Implementierung
}

double my_cost_function(std::vector&lt;double&gt;::iterator begin_, std::vector&lt;double&gt;::iterator end_)
{
	return 1.0; // Nur ein Beispiel
}

int main()
{
	min_options&lt;double&gt; my_options;
	my_options.tolerance = 1.0e-9; // Toleranz festlegen

	minimize(my_cost_function, my_options); // Minimiere &quot;my_cost_function&quot; mit optionen &quot;my_options&quot;

}
</code></pre>
<p>Die Funktion minimize soll ein Optionen-struct mitübergeben bekommen. Dieses soll sich korrekt selbst instanziieren, und zwar in Abhängigkeit des Rückgabewertes der übergebenen Kostenfunktion (hier: my_cost_function). Da in diesem Beispiel die Kostenfunktion double zurückgibt, soll der Aufruf von minimize double als template Parameter für das struct verwenden.</p>
<p>Problem ist jetzt dass ich um decltype zu verwenden ja die genaue Funktionssignatur mit deren Typen kennen müsste (hier: std::vector&lt;double&gt;::iterator). Daher meine Frage, kann man sich nicht irgendwie einfach nur den Rückgabe-Typen einer Funktion holen, ohne dessen Funktionssignatur kennen zu müssen (wie bei decltype nötig)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416378</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416378</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sat, 06 Sep 2014 18:21:36 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Sat, 06 Sep 2014 18:31:27 GMT]]></title><description><![CDATA[<pre><code>min_options&lt;typename std::result_of&lt;cost_function&gt;::type&gt; const &amp;opts
</code></pre>
<p>?</p>
<p>Edit: Ist natürlich Unsinn - nimm</p>
<pre><code>min_options&lt;typename std::function&lt;cost_function&gt;::result_type&gt; const &amp;opts
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2416379</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416379</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sat, 06 Sep 2014 18:31:27 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Sat, 06 Sep 2014 18:51:43 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Edit: Ist natürlich Unsinn - nimm</p>
<pre><code>min_options&lt;typename std::function&lt;cost_function&gt;::result_type&gt; const &amp;opts
</code></pre>
</blockquote>
<p>Sehr schön, das klappt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>An std::function hab ich in diesem Zusammenhang gar nicht gedacht, vielen Dank <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416381</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416381</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sat, 06 Sep 2014 18:51:43 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Mon, 08 Sep 2014 08:51:32 GMT]]></title><description><![CDATA[<p>Hallo nochmal,</p>
<p>es gibt doch noch ein Problem mit dieser Lösung, wie ich gerade festgestellt habe. Und zwar scheint das mit std::function nicht zu funktionieren wenn die übergebene Funktion ein lambda ist, also so:</p>
<pre><code>#include &lt;vector&gt;
#include &lt;functional&gt;

template &lt;typename T&gt;
struct min_options
{
    T tolerance; // Ein paar Optionen
};

template &lt;typename cost_function&gt;
void minimize(cost_function &amp;function_, min_options&lt;typename std::function&lt;cost_function&gt;::result_type&gt; const &amp;opts)
{
    // Hier Implementierung
}

double my_cost_function(std::vector&lt;double&gt;::iterator begin_, std::vector&lt;double&gt;::iterator end_)
{
    return 1.0; // Nur ein Beispiel
}

int main()
{
    min_options&lt;double&gt; my_options;
    my_options.tolerance = 1.0e-9; // Toleranz festlegen

 	using iter = std::vector&lt;double&gt;::iterator;
 	auto my_cost_lambda = [](iter begin_, iter end_) { return 1.0; };

    minimize(my_cost_function, my_options); // Geht 
    minimize(my_cost_lambda, my_options); // Geht nicht

}
</code></pre>
<p>Fehlermeldung ist <em>&quot;error: no matching function for call to ‘minimize(main()::__lambda0&amp;, min_options&lt;double&gt;&amp;)’&quot;</em></p>
<p>Kann man das noch so erweitern dass es für lambdas auch funktioniert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416506</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416506</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Mon, 08 Sep 2014 08:51:32 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Mon, 08 Sep 2014 21:40:57 GMT]]></title><description><![CDATA[<p>Ich denke mir das etwa so:</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;functional&gt;

template&lt;typename T&gt; struct function_result {
  using type = typename function_result&lt;decltype(&amp;T::operator())&gt;::type;
};

template&lt;typename R, typename C, typename... A&gt; struct function_result&lt;R (C::*)(A...) const&gt; { using type = R; };
template&lt;typename R, typename C, typename... A&gt; struct function_result&lt;R (C::*)(A...)      &gt; { using type = R; };
template&lt;typename R,             typename... A&gt; struct function_result&lt;R       (A...)      &gt; { using type = R; };
template&lt;typename R,             typename... A&gt; struct function_result&lt;R    (*)(A...)      &gt; { using type = R; };

template &lt;typename T&gt;
struct min_options
{
    T tolerance; // Ein paar Optionen
};

template &lt;typename cost_function&gt;
void minimize(cost_function &amp;, min_options&lt;typename function_result&lt;cost_function&gt;::type&gt; const &amp;)
{
    // Hier Implementierung
}

double my_cost_function(std::vector&lt;double&gt;::iterator, std::vector&lt;double&gt;::iterator)
{
    return 1.0; // Nur ein Beispiel
}

int main()
{
    min_options&lt;double&gt; my_options;
    my_options.tolerance = 1.0e-9; // Toleranz festlegen

    using iter = std::vector&lt;double&gt;::iterator;
    auto my_cost_lambda = [](iter, iter) { return 1.0; };

    minimize(my_cost_function, my_options); // Geht nicht
    minimize(my_cost_lambda, my_options); // Geht nicht
}
</code></pre>
<p>Da Lambdas ja einen operator() haben müssen, kann man den dafür missbrauchen. Allerdings wird das mit generalisierten Lambdas aus C++14 wohl nicht funktionieren, und andere Funktionsobjekte mit überladenem operator() wird das auch nicht abhandeln können.</p>
<p>Um das Problem ganz allgemein aufzulösen, muss man den Funktionsaufruf etwas genauer spezifizieren (mit Parametern). Wir hatten ja gerade erst <a href="http://www.c-plusplus.net/forum/327834" rel="nofollow">einen ganz ähnlichen Fall</a>, dessen Ansatz wir weiterspinnen können. Etwa so:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; T &amp;dummy_obj() { return *static_cast&lt;T*&gt;(0); }

template &lt;typename cost_function&gt;
void minimize(cost_function &amp;, min_options&lt;decltype(dummy_obj&lt;cost_function&gt;()(dummy_obj&lt;std::vector&lt;double&gt;::iterator&gt;(),
                                                                               dummy_obj&lt;std::vector&lt;double&gt;::iterator&gt;()))&gt; const &amp;)
{
    // Hier Implementierung
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2416597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416597</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 08 Sep 2014 21:40:57 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Mon, 08 Sep 2014 21:48:37 GMT]]></title><description><![CDATA[<pre><code>template&lt;typename T&gt; struct function_result {
  using type = typename function_result&lt;decltype(&amp;T::operator())&gt;::type;
};

template&lt;typename R, typename C, typename... A&gt; struct function_result&lt;R (C::*)(A...) const&gt; { using type = R; };
template&lt;typename R, typename C, typename... A&gt; struct function_result&lt;R (C::*)(A...)      &gt; { using type = R; };
template&lt;typename R,             typename... A&gt; struct function_result&lt;R       (A...)      &gt; { using type = R; };
template&lt;typename R,             typename... A&gt; struct function_result&lt;R    (*)(A...)      &gt; { using type = R; };
</code></pre>
<p>Genau dasselbe wollte ich auch posten.</p>
<p>Für <code>operator()</code> -Templates muss man natürlich die Argumente kennen, da der Rückgabetyp ja von diesen abhängen kann.</p>
<p>Und warum <code>dummy_obj</code> anstatt <code>std::declval</code> ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416598</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416598</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 08 Sep 2014 21:48:37 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Mon, 08 Sep 2014 22:17:28 GMT]]></title><description><![CDATA[<p>Weil ich declval gerade nicht auf dem Schirm hatte. Ist ein guter Einwand, sollte ersetzt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416600</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416600</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 08 Sep 2014 22:17:28 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Tue, 09 Sep 2014 07:11:02 GMT]]></title><description><![CDATA[<p>seldon schrieb:</p>
<blockquote>
<p>Da Lambdas ja einen operator() haben müssen, kann man den dafür missbrauchen. Allerdings wird das mit generalisierten Lambdas aus C++14 wohl nicht funktionieren, und andere Funktionsobjekte mit überladenem operator() wird das auch nicht abhandeln können.</p>
</blockquote>
<p>Dass Lambdas gemäss Standard einen solchen Operator haben müssen wusste ich nicht. Du scheinst aber recht zu haben:</p>
<p>N3337 [expr.prim.lambda] Klausel 5 schrieb:</p>
<blockquote>
<p>The closure type for a lambda-expression has a public inline function call operator (13.5.4) whose parameters<br />
and return type are described by the lambda-expression’s parameter-declaration-clause and trailing<br />
return-type respectively. This function call operator is declared const (9.3.1) if and only if the lambda-<br />
expression’s parameter-declaration-clause is not followed by mutable. It is neither virtual nor declared<br />
volatile. Default arguments (8.3.6) shall not be specified in the parameter-declaration-clause of a lambda-<br />
declarator. Any exception-specification specified on a lambda-expression applies to the corresponding function<br />
call operator. An attribute-specifier-seq in a lambda-declarator appertains to the type of the corresponding<br />
function call operator. [ Note: Names referenced in the lambda-declarator are looked up in the context in<br />
which the lambda-expression appears. —end note ]</p>
</blockquote>
<p>Interessant finde ich auch die darauffolgende Klausel:</p>
<p>N3337 [expr.prim.lambda] Klausel 6 schrieb:</p>
<blockquote>
<p>The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const<br />
conversion function to pointer to function having the same parameter and return types as the closure type’s<br />
function call operator. The value returned by this conversion function shall be the address of a function<br />
that, when invoked, has the same effect as invoking the closure type’s function call operator.</p>
</blockquote>
<p>Das wusste ich auch nicht. Damit und mit SFINAE (und mit Klausel 3) lässt sich doch ein ziemlich gutes <code>is_closure</code> für capturefreie Closures schreiben (zumindest in C++11).<br />
Ausserdem sind diese Klauseln in neueren WDs (z.B. N3690) noch interessanter wegen der Generizität.</p>
<p>Achja, du hast übrigens die Spezialisierung von <code>function_result</code> für variadische Varianten vergessen. Dazu einfach bei allen Versionen <code>(A...)</code> durch <code>(A..., ...)</code> ersetzen.</p>
<p>Edit: Bei MSVC wurden diese Details natürlich nicht korrekt implementiert. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416629</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416629</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 09 Sep 2014 07:11:02 GMT</pubDate></item><item><title><![CDATA[Reply to decltype mit unbekannten Parametern als Parameter on Tue, 09 Sep 2014 17:54:45 GMT]]></title><description><![CDATA[<p>Hm, das wird komplizierter als gedacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Danke auf jeden Fall für die Antworten, wer mal weiter rumprobieren ob ich das so implementiert bekomme (wobei ich wenn ich mir den letzten Post anschaue befürchte dass VS da mal wieder buggy ist...)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2416712</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2416712</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Tue, 09 Sep 2014 17:54:45 GMT</pubDate></item></channel></rss>