<?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[Verflixter Template-Fehler?]]></title><description><![CDATA[<p>Hallo!<br />
ich will mal einen ganz primitiven Binärbaum programmieren. Gleichzeitig würde ich gerne ein wenig C++0x machen ---&gt; benutze als IDE Visual Studio 2010 Beta 1.</p>
<p>Beim kompilieren bekommen ich folgenden Fehler:</p>
<p><code>term does not evaluate to a function taking 2 arguments	[...]xxcallobj</code></p>
<p>Und da ist der Hund begraben: der Fehlercode in irgend einer Standard-Datei. Das stand in der Fehlerausgabe:</p>
<pre><code>c:\programme\microsoft visual studio 10.0\vc\include\xxfunction(226) : see reference to function template instantiation 'void std::tr1::_Function_impl2&lt;_Ret,_Arg0,_Arg1&gt;::_Reset0o&lt;_Myimpl,_Fty,std::allocator&lt;_Ty&gt;&gt;(_Fty,_Alloc)' being compiled
1&gt;          with
1&gt;          [
1&gt;              _Ret=bool,
1&gt;              _Arg0=const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,
1&gt;              _Arg1=const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,
1&gt;              _Fty=std::pair&lt;std::string,int&gt;,
1&gt;              _Ty=std::tr1::_Function_impl2&lt;bool,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;&gt;,
1&gt;              _Alloc=std::allocator&lt;std::tr1::_Function_impl2&lt;bool,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;&gt;&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\node.hpp(55) : see reference to function template instantiation 'std::tr1::function&lt;_Fty&gt;::function&lt;K&gt;(_Fx)' being compiled
1&gt;          with
1&gt;          [
1&gt;              _Fty=bool (const std::string &amp;,const std::string &amp;),
1&gt;              K=std::pair&lt;std::string,int&gt;,
1&gt;              _Fx=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\node.hpp(47) : while compiling class template member function 'std::pair&lt;_Ty1,_Ty2&gt; node&lt;key_type,value_type,struct_type&gt;::insert(const struct_type &amp;)'
1&gt;          with
1&gt;          [
1&gt;              _Ty1=const int *,
1&gt;              _Ty2=bool,
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              struct_type=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\tree.hpp(27) : see reference to class template instantiation 'node&lt;key_type,value_type,struct_type&gt;' being compiled
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              struct_type=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\tree.hpp(26) : while compiling class template member function 'tree&lt;key_type,value_type&gt;::tree(std::tr1::function&lt;_Fty&gt; &amp;&amp;)'
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              _Fty=bool (const std::string &amp;,const std::string &amp;)
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\main.cpp(16) : see reference to class template instantiation 'tree&lt;key_type,value_type&gt;' being compiled
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int
1&gt;          ]
</code></pre>
<p>blabla usw.<br />
Scheinbar passt dem Compiler irgendwas nicht an meiner Anwendung von std::function, oder?<br />
Das kommt so in meinem Code vor:</p>
<pre><code class="language-cpp">// main.cpp:
// Anbei, ein Tree mit String als Schlüssel und int als Speicherwert
// das Lambda soll eine Vergleichsfunktion für Strings sein
tree&lt;string, int&gt; t1([&amp;](const string s1, const string s2) -&gt; bool {
		unsigned short min_len = (s1.length() &gt; s2.length()) ? s2.length() : s1.length();
		for(size_t i = 0; i &lt; min_len; i++) {
			if(s1[i] &gt; s2[i])
				return true;
			else if(s1[i] &lt; s2[i])
				return false;
		}
	});

// den speichere ich in Tree so ab:

typedef std::function&lt;bool (const key_type&amp;, const key_type&amp;)&gt; comp_fun;
comp_fun compare;

// C-tor von tree, Übergabe als Rvalue ok?
template &lt;typename T, typename U, typename K&gt;
tree&lt;T, U, K&gt;::tree(comp_fun &amp;&amp;cmp) : compare(cmp) {
	root = new node&lt;T, U, K&gt;(cmp);
}

// C-tor von node
template &lt;typename T, typename U, typename K&gt;
node&lt;T, U, K&gt;::node(comp_fun cmp)
	: compare(cmp)
{ }

// Anwendungsversuch beim Einfügen in den Baum

if(compare(val_rep.first, s.first)) { // rufe es als Funktion auf
		if(bough.first == 0) {
			bough.first = new node&lt;T, U, K&gt;(s);
			return std::pair&lt;const U*, bool&gt;(&amp;(s.second), true);
		}
		else {
			return bough.first-&gt;insert(s);
		}
	}
</code></pre>
<p>Das ist alles verdammt verflixt. Weiß jemand, wie ich das irgendwie aufrollen und lösen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/250773/verflixter-template-fehler</link><generator>RSS for Node</generator><lastBuildDate>Tue, 15 Sep 2026 20:52:51 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/250773.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 23 Sep 2009 19:49:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verflixter Template-Fehler? on Wed, 23 Sep 2009 19:49:18 GMT]]></title><description><![CDATA[<p>Hallo!<br />
ich will mal einen ganz primitiven Binärbaum programmieren. Gleichzeitig würde ich gerne ein wenig C++0x machen ---&gt; benutze als IDE Visual Studio 2010 Beta 1.</p>
<p>Beim kompilieren bekommen ich folgenden Fehler:</p>
<p><code>term does not evaluate to a function taking 2 arguments	[...]xxcallobj</code></p>
<p>Und da ist der Hund begraben: der Fehlercode in irgend einer Standard-Datei. Das stand in der Fehlerausgabe:</p>
<pre><code>c:\programme\microsoft visual studio 10.0\vc\include\xxfunction(226) : see reference to function template instantiation 'void std::tr1::_Function_impl2&lt;_Ret,_Arg0,_Arg1&gt;::_Reset0o&lt;_Myimpl,_Fty,std::allocator&lt;_Ty&gt;&gt;(_Fty,_Alloc)' being compiled
1&gt;          with
1&gt;          [
1&gt;              _Ret=bool,
1&gt;              _Arg0=const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,
1&gt;              _Arg1=const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,
1&gt;              _Fty=std::pair&lt;std::string,int&gt;,
1&gt;              _Ty=std::tr1::_Function_impl2&lt;bool,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;&gt;,
1&gt;              _Alloc=std::allocator&lt;std::tr1::_Function_impl2&lt;bool,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;,const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt; &amp;&gt;&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\node.hpp(55) : see reference to function template instantiation 'std::tr1::function&lt;_Fty&gt;::function&lt;K&gt;(_Fx)' being compiled
1&gt;          with
1&gt;          [
1&gt;              _Fty=bool (const std::string &amp;,const std::string &amp;),
1&gt;              K=std::pair&lt;std::string,int&gt;,
1&gt;              _Fx=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\node.hpp(47) : while compiling class template member function 'std::pair&lt;_Ty1,_Ty2&gt; node&lt;key_type,value_type,struct_type&gt;::insert(const struct_type &amp;)'
1&gt;          with
1&gt;          [
1&gt;              _Ty1=const int *,
1&gt;              _Ty2=bool,
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              struct_type=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\tree.hpp(27) : see reference to class template instantiation 'node&lt;key_type,value_type,struct_type&gt;' being compiled
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              struct_type=std::pair&lt;std::string,int&gt;
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\tree.hpp(26) : while compiling class template member function 'tree&lt;key_type,value_type&gt;::tree(std::tr1::function&lt;_Fty&gt; &amp;&amp;)'
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int,
1&gt;              _Fty=bool (const std::string &amp;,const std::string &amp;)
1&gt;          ]
1&gt;          c:\dokumente und einstellungen\ad acta\desktop\c++\algorythm\algorythm\main.cpp(16) : see reference to class template instantiation 'tree&lt;key_type,value_type&gt;' being compiled
1&gt;          with
1&gt;          [
1&gt;              key_type=std::string,
1&gt;              value_type=int
1&gt;          ]
</code></pre>
<p>blabla usw.<br />
Scheinbar passt dem Compiler irgendwas nicht an meiner Anwendung von std::function, oder?<br />
Das kommt so in meinem Code vor:</p>
<pre><code class="language-cpp">// main.cpp:
// Anbei, ein Tree mit String als Schlüssel und int als Speicherwert
// das Lambda soll eine Vergleichsfunktion für Strings sein
tree&lt;string, int&gt; t1([&amp;](const string s1, const string s2) -&gt; bool {
		unsigned short min_len = (s1.length() &gt; s2.length()) ? s2.length() : s1.length();
		for(size_t i = 0; i &lt; min_len; i++) {
			if(s1[i] &gt; s2[i])
				return true;
			else if(s1[i] &lt; s2[i])
				return false;
		}
	});

// den speichere ich in Tree so ab:

typedef std::function&lt;bool (const key_type&amp;, const key_type&amp;)&gt; comp_fun;
comp_fun compare;

// C-tor von tree, Übergabe als Rvalue ok?
template &lt;typename T, typename U, typename K&gt;
tree&lt;T, U, K&gt;::tree(comp_fun &amp;&amp;cmp) : compare(cmp) {
	root = new node&lt;T, U, K&gt;(cmp);
}

// C-tor von node
template &lt;typename T, typename U, typename K&gt;
node&lt;T, U, K&gt;::node(comp_fun cmp)
	: compare(cmp)
{ }

// Anwendungsversuch beim Einfügen in den Baum

if(compare(val_rep.first, s.first)) { // rufe es als Funktion auf
		if(bough.first == 0) {
			bough.first = new node&lt;T, U, K&gt;(s);
			return std::pair&lt;const U*, bool&gt;(&amp;(s.second), true);
		}
		else {
			return bough.first-&gt;insert(s);
		}
	}
</code></pre>
<p>Das ist alles verdammt verflixt. Weiß jemand, wie ich das irgendwie aufrollen und lösen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1783269</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1783269</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Wed, 23 Sep 2009 19:49:18 GMT</pubDate></item><item><title><![CDATA[Reply to Verflixter Template-Fehler? on Fri, 25 Sep 2009 03:34:22 GMT]]></title><description><![CDATA[<p>STLFilt könnte dir das Leben vielleicht bissl einfacher machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1783872</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1783872</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Fri, 25 Sep 2009 03:34:22 GMT</pubDate></item><item><title><![CDATA[Reply to Verflixter Template-Fehler? on Fri, 25 Sep 2009 08:16:31 GMT]]></title><description><![CDATA[<p>Hier ein paar Kommentare zum Stil:</p>
<p>Warum schreibst Du eine Tree-Klasse, wenn Du std::map benutzen kannst?</p>
<p>Warum legst Du Dich eigentlich auf std::function fest? Du kannst den Typ des Komparators doch genauso als Template-Parameter einführen. Du kannst dann ja immer noch std::function&lt;&gt; als Template-Parameter benutzen und dem Konstructor ein Lambda-Objekt übergeben. std::less als Default ist einfach extrem praktisch.</p>
<pre><code class="language-cpp">typedef map&lt;string,dings,
           function&lt;bool(string const&amp;, string const&amp;)&gt; &gt; map_type;

map_type meine_map (
  [](string const&amp; a, string const&amp; b) {
    return a &lt; b;
  }
);
</code></pre>
<p>Wenn Dein Compiler auch schon &quot;template typedefs&quot; unterstützt kannst Du ja auch das schreiben:</p>
<pre><code class="language-cpp">template&lt;typename Key, typename Mapped&gt;
using map_polycmp = std::map&lt;Key,Mapped,std::function&lt;bool(Key const&amp;,Key const&amp;)&gt;&gt;;

...

map_polycmp&lt;string,dings&gt; meine_map (
  [](string const&amp;a, string const&amp;b) {
    return a&lt;b;
  }
);
</code></pre>
<p>Man beachte auch, dass die &quot;capture-clause&quot; leer ([] statt [&amp;]) ist. Es wird keine Refenz auf den umliegenden scope benötigt.</p>
<p>Die Übergabe des Komparators (&quot;comp_t &amp;&amp; comp&quot;) ist unpraktisch. Du kannst so ja nur Rvalues entgegennehmen und keine Lvalues (!). Du bräuchtest also noch einen comp_t const&amp; overload. Wenn Du aber einen halbwegs brauchbaren Compiler hast, kannst Du auch einfach pass-by-value benutzen, ohne dass die Performanz auch nur ein bischen leidet. Der Compiler sollte hier bei Übergabe eines Lambda-Objektes fähig sein, eine &quot;copy elision&quot; durchzuführen. Damit kannst Du Dir die &amp;&amp;/const&amp;-overload Geschichte sparen. Benutze aber reichlich <code>std::move</code> stattdessen:</p>
<pre><code class="language-cpp">// C-tor von tree
template &lt;typename T, typename U, typename K&gt;
tree&lt;T, U, K&gt;::tree(comp_fun cmp)
: compare( std::move(cmp) ) // cmp wird ja nicht mehr benötigt.
{
    root = 0; // Ein &quot;leerer Baum&quot;, sollte ohne new auskommen!
}
</code></pre>
<p>Es sieht auch so aus, als ob alle Deine Knoten jeweils eine <em>Kopie</em> des Komparators speichern. Das ist nicht nötig und kann sehr teuer werden, wenn der Comparator &quot;unhandlich&quot; ist. Wenn Du std::function-Ojekte kopierst und für das Funktion-Objekt keine &quot;small function optimization&quot; durchgeführt wird, wird für die neue Kopie der Freispeicher beantsprucht.</p>
<p>Sonst: Versuch mal den Fehler zu isolieren.</p>
<p>BTW: Im Englischen heißt das &quot;algorithm&quot;, also ohne y</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1783894</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1783894</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Fri, 25 Sep 2009 08:16:31 GMT</pubDate></item><item><title><![CDATA[Reply to Verflixter Template-Fehler? on Fri, 25 Sep 2009 10:49:14 GMT]]></title><description><![CDATA[<p>Herzlichen Dank für deine Kritik.</p>
<p>Ich werde mal schauen, dass ich den Lambda-Functor zum Vergleichen in die Tpl-Liste übergebe.<br />
Mit der Template-Übergabe müsste ja dann auch das Problem der vielen Kopien des Compare-Functos erledigt sein. Den Fehler habe ich in den const-Wursteleien gefunden. Ich habe jetzt beim insert() die const in den call-by-references entfernt, die Elemente werden eh nicht verändert und für diese Garantie kann man als Template-Parameter ja auch einen konstanten Typ angeben. Es war also irgendsowas wie ein Konvertierungsproblem in einem Konstruktor durch const.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1784051</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1784051</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Fri, 25 Sep 2009 10:49:14 GMT</pubDate></item></channel></rss>