<?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[Template-Methode (Operator) mit Template spezialisieren]]></title><description><![CDATA[<p>Folgende Situation:</p>
<pre><code class="language-cpp">class ByteStreamWriter
{
public:

	template &lt;class T&gt;
	ByteStreamWriter &amp;operator &lt;&lt; (const T &amp;value)
	{
		//...
		return *this;
	}
};

//jetzt würde ich gerne festlegen, wie vector2d gehandhabt wird, aber für ein beliebiges T
template &lt;class T&gt;
Stream &amp;operator &lt;&lt; (ByteStreamWriter &amp;bsw, const vector2d&lt;T&gt; &amp;value)
{
	//...
	return bsw;
}

//...

ByteStreamWriter bsw;
bsw &lt;&lt; vector2d&lt;int&gt;(); //Fehler
</code></pre>
<p>Dieses Problem gibts bei MinGW, jedoch nicht bei VC++:<br />
`</p>
<p>C:...\header.h|173|error: ambiguous overload for 'operator&lt;&lt;' in '... (irgendeine Funktion eben)'|</p>
<p>`</p>
<p>Was kann man da machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/260989/template-methode-operator-mit-template-spezialisieren</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 18:15:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/260989.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 11 Feb 2010 19:28:00 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 20:36:33 GMT]]></title><description><![CDATA[<p>Folgende Situation:</p>
<pre><code class="language-cpp">class ByteStreamWriter
{
public:

	template &lt;class T&gt;
	ByteStreamWriter &amp;operator &lt;&lt; (const T &amp;value)
	{
		//...
		return *this;
	}
};

//jetzt würde ich gerne festlegen, wie vector2d gehandhabt wird, aber für ein beliebiges T
template &lt;class T&gt;
Stream &amp;operator &lt;&lt; (ByteStreamWriter &amp;bsw, const vector2d&lt;T&gt; &amp;value)
{
	//...
	return bsw;
}

//...

ByteStreamWriter bsw;
bsw &lt;&lt; vector2d&lt;int&gt;(); //Fehler
</code></pre>
<p>Dieses Problem gibts bei MinGW, jedoch nicht bei VC++:<br />
`</p>
<p>C:...\header.h|173|error: ambiguous overload for 'operator&lt;&lt;' in '... (irgendeine Funktion eben)'|</p>
<p>`</p>
<p>Was kann man da machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854358</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854358</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Thu, 11 Feb 2010 20:36:33 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 20:05:32 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Was kann man da machen?</p>
</blockquote>
<p>Was willst du denn? Spezialisierung liegt hier nicht vor und ohne den fehlerverursachenden Ausdruck, die verwendeten Typen und die vollständige Fehlermeldung kann man nur raten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854373</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854373</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Feb 2010 20:05:32 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 20:37:04 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Spezialisierung liegt hier nicht vor</p>
</blockquote>
<p>Ja eben, das ist das Problem. Das habe ich vielleicht nicht deutlich gesagt.</p>
<p>camper schrieb:</p>
<blockquote>
<p>ohne den fehlerverursachenden Ausdruck, die verwendeten Typen und die vollständige Fehlermeldung kann man nur raten.</p>
</blockquote>
<p>Tut mir Leid, ich war mit den Gedanken nicht ganz bei der Sache.</p>
<p>`</p>
<p>C:....\filedb.h|173|error: ambiguous overload for 'operator&lt;&lt;' in 'bsw &lt;&lt; ((const stx::fdb::GetSetField&lt;stx::vector2d<a href="stx::uint32" rel="nofollow">stx::uint32</a> &gt;*)this)-&gt;stx::fdb::GetSetField&lt;stx::vector2d<a href="stx::uint32" rel="nofollow">stx::uint32</a> &gt;::m_value'|</p>
<p>C:....\bytestreamwriter.h|108|note: candidates are: stx::ByteStreamWriter&amp; stx::ByteStreamWriter::operator&lt;&lt;(const T&amp;) [with T = stx::vector2d<a href="stx::uint32" rel="nofollow">stx::uint32</a>]|</p>
<p>C:....\vector2d.h|237|note:                 stx::ByteStreamWriter&amp; stx::operator&lt;&lt;(stx::ByteStreamWriter&amp;, const stx::vector2d&lt;T&gt;&amp;) [with T = stx::uint32]|</p>
<p>C:....\filedb.h||In member function `void stx::fdb::GetSetField&lt;T&gt;::serialize(stx::ByteStreamWriter&amp;) const [with T = stx::vector2d<a href="stx::sint32" rel="nofollow">stx::sint32</a>]':|</p>
<p>`</p>
<p>Die Meldung bezieht sich auf <code>vector2d&lt;T&gt;</code> , was hier aber keinen Unterschied macht. Bei <code>std::basic_string</code> ließ sich das Problem &quot;lösen&quot;, indem man für <code>std::string</code> und <code>wstring</code> einzeln spezialisiert hat. Das soll natürlich auch nicht so sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854383</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854383</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Thu, 11 Feb 2010 20:37:04 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 20:37:26 GMT]]></title><description><![CDATA[<p>Verzichte einfach darauf, Operatoren als Member zu definieren. Dafür gibt es ohnehin oft genug keinen Grund. Existieren beide Operatoren als freie Funktionen, ist die Überladung wieder eindeutig, da das eine Template spezieller als das andere ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854393</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854393</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Feb 2010 20:37:26 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 21:00:51 GMT]]></title><description><![CDATA[<p>Danke, das hat geholfen, auch wenn ich nicht verstehe, warum. Weshalb ist ist die Überladung der Methode nicht so speziell?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854404</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854404</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Thu, 11 Feb 2010 21:00:51 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Thu, 11 Feb 2010 22:39:18 GMT]]></title><link>https://www.c-plusplus.net/forum/post/1854432</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854432</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Feb 2010 22:39:18 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Methode (Operator) mit Template spezialisieren on Fri, 12 Feb 2010 11:09:45 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Danke, das hat geholfen, auch wenn ich nicht verstehe, warum. Weshalb ist ist die Überladung der Methode nicht so speziell?</p>
</blockquote>
<p>Weil die Parameter<em>listen</em> nicht in Übereinstimmung zu bringen sind.</p>
<p>14.5.5.2 schrieb:</p>
<blockquote>
<p>...<br />
2 Given two overloaded function templates, whether one is more specialized than another can be determined by transforming each template in turn and using argument deduction (14.8.2) to compare it to the other.<br />
3 The transformation used is:<br />
— For each type template parameter, synthesize a unique type and substitute that for each occurrence of that parameter in the function parameter list, or for a template conversion function, in the return type.<br />
— For each non-type template parameter, synthesize a unique value of the appropriate type and substitute that for each occurrence of that parameter in the function parameter list, or for a template conversion function, in the return type.<br />
— For each template template parameter, synthesize a unique class template and substitute that for each occurrence of that parameter in the function parameter list, or for a template conversion function, in the return type.<br />
4 Using the transformed function parameter list, perform argument deduction against the other function template. The transformed template is at least as specialized as the other if, and only if, the deduction succeeds and the deduced parameter types are an exact match (so the deduction does not rely on implicit conversions).</p>
</blockquote>
<p>Das implizite Objektargument eines Memberfunktionsaufrufes ist aber nicht Teil der Argumentliste und nimmt nicht an der Templateargumentdeduktion teil. Folglich stimmt die Zahl der Parameter nicht überein und eine partielle Ordnung zwischen memberfunktion und freier Funktion kann nicht etabliert werden.</p>
<p>Bei normalen benannten Funktion besteht dieses Problem nicht in gleicher Weise, da kein Kontext existiert, in dem sowohl Memberfunktionen als auch eine nicht-Member Teil des Kandidatensets eines überladenen Funktionsaufrufes sind (ADL findet nicht statt, wenn beim unqualifizierten Lookup eine Memberfunktion gefunden wird, ADL kann keine Memberfunktionen finden, und unqualifiziertes Lookup kann nicht gleichzeitig Member- und nicht-Memberfunktionen finden).<br />
Partielle Ordnung zwischen nicht-statischen und statsischen Memberfunktionen ist möglich, allerdings besitzen auch nicht-statische Memberfunktionen einen impliziten Objektparameter (13.3.1/4), das stellt also nicht unbedingt eine Besonderheit dar.</p>
<p>Es dürfte genügen, sich zu merken, dass keine partielle Ordnung zwischen überladenen Operatortemplates existiert, die einerseits als nicht-member- und anderseits als Membertemplates überladen wurden.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

struct bar {};

template &lt;typename T&gt; static void f(T*, bar) { std::cout &lt;&lt; &quot;::f\n&quot;; }
template &lt;typename T&gt; static void g(T, bar) { std::cout &lt;&lt; &quot;::g\n&quot;; }

struct foo
{
    template &lt;typename T&gt; static void f(T*, bar) { std::cout &lt;&lt; &quot;static f\n&quot;; }
    template &lt;typename T&gt; static void g(T, bar) { std::cout &lt;&lt; &quot;static g\n&quot;; }
    template &lt;typename T&gt; void f(T, bar) { std::cout &lt;&lt; &quot;nonstatic f\n&quot;; }
    template &lt;typename T&gt; void g(T*, bar) { std::cout &lt;&lt; &quot;nonstatic g\n&quot;; }
    void fun()
    {
        bar b;
        f(&quot;f&quot;,b);
        g(&quot;g&quot;,b);
    }
};

int main()
{
    foo f;
    f.fun();
}
</code></pre>
<p>Ausgabe:</p>
<pre><code>static f
nonstatic g
</code></pre>
<p>Die freien Funktionen werden gar nicht erst betrachtet, weil kein ADL stattfindet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854582</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854582</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 12 Feb 2010 11:09:45 GMT</pubDate></item></channel></rss>