<?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[Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable]]></title><description><![CDATA[<p>Grüsse zusammen,</p>
<p>Ich überlege mir schon etwas länger, ob es eine Lösung für das folgende Problem gibt:</p>
<pre><code class="language-cpp">template&lt;typename ParamT&gt;
void foo(ParamT param)
{
  if(/* param ist eine Funktion oder ein Funktor */)
  {
    param(5);
  }
  else /* param ist eine Variable */
  {
    param = 5;
  }
}
</code></pre>
<p>Da allerdings der Funktor eigentlich eine Variable ist, sehe ich ziemliche Schwierigkeiten hier eine vernünftige Unterscheidung zu finden. Allerdings sehe ich schon gar keine Möglichkeit zwischen Funktion und Variable zu unterscheiden. Gibt es da irgendwelche Möglichkeiten? Oder bleibt einem nichts anderes übrig, als unterschiedliche Funktionsnamen zu nehmen?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/221087/templateparameter-gt-erkennung-von-funktion-funktor-variable</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 06:55:03 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/221087.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 25 Aug 2008 13:12:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 13:12:27 GMT]]></title><description><![CDATA[<p>Grüsse zusammen,</p>
<p>Ich überlege mir schon etwas länger, ob es eine Lösung für das folgende Problem gibt:</p>
<pre><code class="language-cpp">template&lt;typename ParamT&gt;
void foo(ParamT param)
{
  if(/* param ist eine Funktion oder ein Funktor */)
  {
    param(5);
  }
  else /* param ist eine Variable */
  {
    param = 5;
  }
}
</code></pre>
<p>Da allerdings der Funktor eigentlich eine Variable ist, sehe ich ziemliche Schwierigkeiten hier eine vernünftige Unterscheidung zu finden. Allerdings sehe ich schon gar keine Möglichkeit zwischen Funktion und Variable zu unterscheiden. Gibt es da irgendwelche Möglichkeiten? Oder bleibt einem nichts anderes übrig, als unterschiedliche Funktionsnamen zu nehmen?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571068</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 25 Aug 2008 13:12:27 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 13:17:34 GMT]]></title><description><![CDATA[<p>Hier sollte was dabei sein: <a href="http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/index.html" rel="nofollow">http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/index.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571075</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571075</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 25 Aug 2008 13:17:34 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 13:37:01 GMT]]></title><description><![CDATA[<p>Ne, <code>is_function</code> prüft nur, ob man eine Funktion vor sich hat (nichtmal für Funktionszeiger gilt das). Du bräuchtest ein <code>is_callable</code> . Damit und <code>boost::enable_if</code> wäre das leicht zu machen. Mal sehen…</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571095</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571095</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Mon, 25 Aug 2008 13:37:01 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 14:12:20 GMT]]></title><description><![CDATA[<p>Also die Unterscheidung zu Funktionspointer ist ja banal. (Wobei es dann wieder Probleme mit normalen Zeiger gibt.. )</p>
<p>Hmm. Für die Unterscheidung zu Funktoren (ohne Boost) fällt mir nur ein kleines Workaround ein.</p>
<p>Es gibt hald eine Bedingung, wenn man das Template benutzen will.</p>
<pre><code class="language-cpp">class func
{
public:
	void operator ()(int i){}
	void operator = (int i) { this-&gt;operator () (i);}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1571122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571122</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Mon, 25 Aug 2008 14:12:20 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 14:16:39 GMT]]></title><description><![CDATA[<p>Ah <a href="http://www.boost.org/libs/concept_check" rel="nofollow">Concept Checking</a> sollte helfen:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
struct Callable
{
    BOOST_CONCEPT_USAGE(Callable)
    {
        int i;
        f(i);
    }
private:
    T f;
};

template&lt;typename ParamT&gt;
    BOOST_CONCEPT_REQUIRES((Callable&lt;ParamT&gt;), void)
    foo(ParamT param)
{
    param(5);
}

template &lt;typename ParamT&gt;
void foo (ParamT param)
{
    param = 5;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1571130</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571130</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Mon, 25 Aug 2008 14:16:39 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 15:21:21 GMT]]></title><description><![CDATA[<p>Ein allgemeines is_callable dürfte schwierig sein. Referenzen und Zeiger auf Funktionen sind kein Problem.<br />
Bei Funktoren weiß man, dass sie eine entsprechende Memberfunktion haben - dummerweise könnte diese überladen werden oder es könnte sich um ein Membertemplate handeln und dann ist es nicht mehr so einfach. Im konkreten Fall gehe ich aber davon aus, dass das ARgument, mit dem die Funktion aufzurufen wäre, bereits feststeht. Dann ist es relativ einfach</p>
<pre><code class="language-cpp">typedef char no;
typedef no yes[2];
template &lt;typename T&gt;
T&amp; make_T();
template &lt;typename T&gt;
yes&amp; func(T, char(*)[sizeof( make_T&lt;T&gt;()(5) )]=0);
no&amp; func(...);
template &lt;typename T&gt;
struct is_callable_by_5
{
    static const bool value = sizeof( func( make_T&lt;T&gt;() ) ) == sizeof( yes );
};
</code></pre>
<p>Bzgl. concepts: ich hatte den Eindruck, dass mit dem Framework nur eine Überpfrüfung bestimmter Eigenschaften möglich ist (d.h. eine fehlgeschlagene Überprüfung führt zum Abbruch der Compilierung und nicht zur Auswahl eines Alternativen Code-Pfades), aber gerade nicht die Möglichkeit, das Vorliegen von einer Eigenschaft herauszufinden und entsprechend zu reagieren. Habe ich etwas übersehen?<br />
Selbst wenn ich mich irre, funktioniert es jedenfalls nicht so, wie gezeigt. Denn für den callable-Fall hätte man dann zwei Templates, die instantiiert werden können, und keines der Templates ist spezieller als das andere.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571139</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 25 Aug 2008 15:21:21 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 15:00:37 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9606">@.filmor</a>,<br />
1. Es gibt auch noch <code>boost::remove_pointer</code> . In Kombinatin mit <code>boost::is_function</code> ist die Unterscheidung von Variablen und Funktionen möglich:</p>
<pre><code class="language-cpp">template&lt;typename ParamT&gt;
void foo(ParamT&amp; param)
{
  if(boost::is_function&lt;boost::remove_pointer&lt;ParamT&gt; &gt;::value)
  { std::cout &lt;&lt; &quot;function&quot; &lt;&lt; std::endl; }
  else
  { std::cout &lt;&lt; &quot;no function&quot; &lt;&lt; std::endl; }
}
</code></pre>
<p>2. Bei den Concept Checks ist es genau wie camper gesagt hat: Es dient nur zu einer Überprüfung. Dadurch meckert der Compiler bei der Deklaration des zweiten Foo-Funktiontemplates, da dieses Funktionstemplate bereits existiert.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18422">@drakon</a>,<br />
Es würde gerade darum gehen, dass man den User nicht einschränken soll. Zum Beispiel dass er ohne Probleme Boost.Bind verwenden könnte, oder ähnliches, um zum Beispiel auch Memberfunktionen verwenden zu können oder anderes.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>,<br />
Und wenn das Argument nicht feststeht? <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>
<p>Aber ich denke, am einfachsten wäre es, einfach zwei Funktionen anzubieten. Eine Funktion für Callable und eine für Nicht-Callable.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571165</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571165</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 25 Aug 2008 15:00:37 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 15:37:58 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Es gibt auch noch <code>boost::remove_pointer</code> . In Kombinatin mit <code>boost::is_function</code> ist die Unterscheidung von Variablen und Funktionen möglich</p>
</blockquote>
<p>Mir war schon klar, dass das nicht das Problem sein sollte, aber damit hast du keine Funktionsobjekte drin.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Bei den Concept Checks ist es genau wie camper gesagt hat: Es dient nur zu einer Überprüfung. Dadurch meckert der Compiler bei der Deklaration des zweiten Foo-Funktiontemplates, da dieses Funktionstemplate bereits existiert.</p>
</blockquote>
<p>Nö, eigentlich ist das genau die richtige Baustelle für Konzepte (Standardbeispiel ist ja std::sort für RandomAccessIterator und andere). Man müsste halt den zweiten Pfad etwas verlängern. Leite mal nicht aus meiner Unfähigkeit ab, dass Konzepte dafür nicht geeignet sind <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Und wenn das Argument nicht feststeht? <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>
</blockquote>
<p>Es reicht, wenn die Typen der Argumentliste bekannt sind:</p>
<pre><code class="language-cpp">typedef char no;
typedef no yes[2];

template &lt;typename T&gt;
T&amp; make();

template &lt;typename T, typename T1, typename T2, etc.&gt;
struct is_callable_with
{
    struct tester
    {
        static yes&amp; test(
            T const volatile&amp;,
            char(*)[sizeof(make&lt;T&gt;()(make&lt;T1&gt;(), make&lt;T2&gt;(), etc.))] = 0
            );

        static no&amp; test(...);
    };

    static const bool value = sizeof(tester::test(make&lt;T&gt;())) == sizeof( yes );
};
</code></pre>
<p>/edit: Hmm, ne, so klappt das aber nur wenn das fragliche Objekt ne Ganzzahlkonstante zurückliefert, oder?</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Aber ich denke, am einfachsten wäre es, einfach zwei Funktionen anzubieten. Eine Funktion für Callable und eine für Nicht-Callable.</p>
</blockquote>
<p>Ist zumindest sauberer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571182</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571182</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Mon, 25 Aug 2008 15:37:58 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Mon, 25 Aug 2008 15:30:51 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Und wenn das Argument nicht feststeht? <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>
</blockquote>
<p>Das ist schon begrifflich ein Problem. Was heißt das eigentlich, dass eine Entität callable ist, ohne dies gleichzeitig auf ein Argumenttupel zu beziehen?</p>
<pre><code class="language-cpp">class strange
{
private:
    struct stranger {};
public:
    void operator()(stranger) {}
};
</code></pre>
<p>callable oder nicht? Die Klasse hat zwar einen operator (), nur ist es tatsächlich unmöglich, diese Funktion aufzurufen (wir können allerdings noch einen Zeiger auf Member dazu erhalten).</p>
<pre><code class="language-cpp">struct strangest
{
    template&lt;typename T&gt;
    typename enable_if_c&lt;sizeof(T)==0&gt;::type operator()(T);
};
</code></pre>
<p>callable?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571191</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 25 Aug 2008 15:30:51 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Tue, 26 Aug 2008 12:47:32 GMT]]></title><description><![CDATA[<p>Ich habe mir jetzt nochmals Gedanken dazu gemacht und komme endgültig zum Schluss, dass es keine Vernünftige Unterscheidung, zwischen Funktor und Variable gibt. Bzw. unter speziellen Umständen gäbe es womöglich ein paar, allerdings scheint mir es besser zu sein, wenn man es direkt in den Namen der Funktion nimmt. Muss es der Anwender wissen, was er möchte.</p>
<p>Mir kam die Idee ursprünglich davon, dass ich meiner XML Bibliothek eine Möglichkeit schenken wollte, dass man XPaths direkt auf Variablen mappen können soll. Jetzt werde ich es wahrscheinlich so oder so ähnlich lösen:</p>
<pre><code class="language-cpp">// Normale variable, über Zuweisung.
template&lt;typename VarT&gt;
void map(std::string const&amp; xpath, VarT&amp; var);

// Freie Funktion.
template&lt;typename VarT, typename RetT&gt;
void map(std::string const&amp; xpath, RetT (*func)(VarT));

// Member-Funktion, im Visier sind die Setter.
template&lt;typename VarT, typename RetT, typename ClassT&gt;
void map(std::string const&amp; xpath, RetT (ClassT::*func)(VarT), ClassT&amp; obj);

// Möglichkeit für Funktoren. Muss man dann allerdings den Typ von VarT selber angeben.
template&lt;typename VarT, typename CallableT&gt;
void map_callable(std::string const&amp; xpath, CallableT callable);
</code></pre>
<p>Danke für die Antworten!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1571687</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1571687</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 26 Aug 2008 12:47:32 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Wed, 27 Aug 2008 07:22:18 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<pre><code class="language-cpp">class strange
{
private:
    struct stranger {};
public:
    void operator()(stranger) {}
};
</code></pre>
<p>callable oder nicht? Die Klasse hat zwar einen operator (), nur ist es tatsächlich unmöglich, diese Funktion aufzurufen (wir können allerdings noch einen Zeiger auf Member dazu erhalten).</p>
</blockquote>
<p>Den Zeiger auf Member können wir aber nur erhalten wenn strange sowas per typedef publik macht oder? Ich hab jetz keinen Compiler zur Hand, aber müsste es bei sowas nicht Probleme geben:</p>
<pre><code class="language-cpp">class strange {/*wie oben*/};

typedef void (strange::*strange_memfun_ptr)(strange::stranger); //Problem, da strange::stranger private?
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1572033</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1572033</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 27 Aug 2008 07:22:18 GMT</pubDate></item><item><title><![CDATA[Reply to Templateparameter -&amp;gt; Erkennung von Funktion&#x2F;Funktor&#x2F;Variable on Wed, 27 Aug 2008 09:14:11 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">class strange {
private:
    struct stranger {};
public:
    void operator()(stranger) {}
};
template&lt;typename C, typename T&gt;
T get_stranger(void(C::*)(T))
{
    return T();
}
...
strange foo;
foo(get_stranger(&amp;strange::operator()));
</code></pre>
<p>Sobald ein Typ Teil eines öffentlichen Interfaces ist, kommt man prinzipiell heran, auch wenn der Typ selbst private ist. Das ist dann aber wieder Machiavellis Domäne.<br />
Man kann die Frage natürlich auch anders stellen, z.B. indem man den Operator private macht und ggf. eine Handvoll friends hat. Interessiert uns, ob jemand bestimmtes das Objekt mit ganz konkreten Argumenten aufrufen kann, oder ob das irgendjemand irgendwie machen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1572090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1572090</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 27 Aug 2008 09:14:11 GMT</pubDate></item></channel></rss>