<?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[Mehrfache operator[] überladung ist mehrdeutig]]></title><description><![CDATA[<p>Hallo,<br />
ich habe derzeit ein kleines Problem innerhalb einer Datenbankklasse bzw Modulen davon.<br />
Ich stelle das Ergebnis inderekt als<br />
std::vector&lt;std::map<a href="std::string,std::string" rel="nofollow">std::string,std::string</a> &gt; da.<br />
wobei mir der operator[] der erbegnis klasse das objekt zurückgibt, welches die map beinhaltet.<br />
Bei diesem &quot;Row&quot;-Object habe ich nun den operator[] mal überladen:</p>
<pre><code class="language-cpp">const std::string operator[](const std::string &amp;key){return data_map_[key];}
  	const std::string operator[](const int &amp;index)const{return values_[index];}
</code></pre>
<p>data_map_ ist hierbei die genannte map und values_ ein std::vector<a href="std::string" rel="nofollow">std::string</a><br />
der quasi nur die werte der map beinhaltet.</p>
<p>Der Zugriff über den int-Index und auch der über den string funktionieren wie<br />
gewollt, aber wenn ich beide operatoren in der klasse lasse, bekomme ich:</p>
<blockquote>
<p>error: ISO C++ says that <code>const std::string libdb::db_row::operator\[\](const int&amp;) const' and</code>const std::string<br />
libdb::db_row::operator[](const std::string&amp;)' are ambiguous even though the<br />
worst conversion for the former is better than the worst conversion for the latter</p>
</blockquote>
<p>Der Aufruf bei dem der Fehler auftritt ist:</p>
<pre><code class="language-cpp">std::string name=res[0][0];
</code></pre>
<p>Es liegt also afaik daran, dass er aus int nen std::string machen kann.<br />
Ich hab denn mal statt std::string const char* genommen, aber da bekam ich<br />
in der umgekehrte Situation einen Fehler.<br />
Wisst Ihr woran es nun liegt; oder viel eher, wie ich dieses Problem umgehen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/151458/mehrfache-operator-überladung-ist-mehrdeutig</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 12:09:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/151458.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 26 Jun 2006 14:22:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 14:22:15 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich habe derzeit ein kleines Problem innerhalb einer Datenbankklasse bzw Modulen davon.<br />
Ich stelle das Ergebnis inderekt als<br />
std::vector&lt;std::map<a href="std::string,std::string" rel="nofollow">std::string,std::string</a> &gt; da.<br />
wobei mir der operator[] der erbegnis klasse das objekt zurückgibt, welches die map beinhaltet.<br />
Bei diesem &quot;Row&quot;-Object habe ich nun den operator[] mal überladen:</p>
<pre><code class="language-cpp">const std::string operator[](const std::string &amp;key){return data_map_[key];}
  	const std::string operator[](const int &amp;index)const{return values_[index];}
</code></pre>
<p>data_map_ ist hierbei die genannte map und values_ ein std::vector<a href="std::string" rel="nofollow">std::string</a><br />
der quasi nur die werte der map beinhaltet.</p>
<p>Der Zugriff über den int-Index und auch der über den string funktionieren wie<br />
gewollt, aber wenn ich beide operatoren in der klasse lasse, bekomme ich:</p>
<blockquote>
<p>error: ISO C++ says that <code>const std::string libdb::db_row::operator\[\](const int&amp;) const' and</code>const std::string<br />
libdb::db_row::operator[](const std::string&amp;)' are ambiguous even though the<br />
worst conversion for the former is better than the worst conversion for the latter</p>
</blockquote>
<p>Der Aufruf bei dem der Fehler auftritt ist:</p>
<pre><code class="language-cpp">std::string name=res[0][0];
</code></pre>
<p>Es liegt also afaik daran, dass er aus int nen std::string machen kann.<br />
Ich hab denn mal statt std::string const char* genommen, aber da bekam ich<br />
in der umgekehrte Situation einen Fehler.<br />
Wisst Ihr woran es nun liegt; oder viel eher, wie ich dieses Problem umgehen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086024</guid><dc:creator><![CDATA[shapeless]]></dc:creator><pubDate>Mon, 26 Jun 2006 14:22:15 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 15:13:10 GMT]]></title><description><![CDATA[<p>zeig mal die definition deiner db_row klasse.</p>
<p>const std::string operator[](const std::string &amp;key){return data_map_[key];}<br />
const std::string operator[](const int &amp;index)const{return values_[index];}</p>
<p>damit Hasst du: instanz[const int &amp; index] und instanz[std::string &amp;key] realisiert.</p>
<p>also ein res[0] liefert dir ein std::string zurueck (ich nehm an res ist vom typ db_row oder ? )<br />
ein res[0][0] -&gt; ist also ain std::string[0] = eine referenz auf nen char<br />
std::string name=res[0][0]; ist also ne zuweisung eines chars an nen std::string.</p>
<p>Ist dass den definiert ? und wenn, dann ist es sicher nich was zu erwartest ^^</p>
<p>Was ist denn dein uebergeordnetes object(resultset) fuer mehrere rows ?<br />
das muesste ja dann nen operator ala:</p>
<p>db_row &amp; operator[](unsigned int index);<br />
const db_row &amp; operator[](unsigned int index) const;</p>
<p>haben. wein dein res obejct von dem typ waer, muesste es funktionieren.</p>
<p>Noch was anderes (const unsigned int &amp; ) macht kaum sinn ....<br />
wenn ich es nicht veraendern darf, macht ne referenz als rueckgabe logisch keinen sinn<br />
ne kopie von int mittels ner referenz zu vermeiden auch nicht, weil referenz und int wahrscheinlich die selbe groesse haben ...<br />
das der compiler da was mehr optimiert, ist eher auch unwahrscheinlich, wenn ers kann und inlined wird er auch ohne referenz erkennen das er direkt auf die variable ohne probs zugreifen kann ...</p>
<p>nimm lieber (unsigend int index)</p>
<p>und deinen key bei (std:string &amp; key) darf er veraendern ???</p>
<p>Ciao ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086059</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086059</guid><dc:creator><![CDATA[RHBaum]]></dc:creator><pubDate>Mon, 26 Jun 2006 15:13:10 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 15:26:26 GMT]]></title><description><![CDATA[<p>sorry, wie gesagt ich hatte es kurz mit const char* probiert,<br />
beim zurücksetzten hab ich wohl das const des std::string versehentlich entfernt.<br />
Zur referenz aufs int kann ich dir zustimmen.<br />
Und die const zurückgabe macht doch sinn, weil ich es nicht verändern will,<br />
sondern nur bekommen und weiterverwenden. Dennoch ist wohl zu überlegen obs grundsetzlich nützlich wäre.</p>
<p>Zur Frage: Tut mir leid der Aufruf war missverständlich.<br />
Wie du schon sagst, es gibt ein result objekt, dass einen operator[] hat:</p>
<pre><code class="language-cpp">typedef db_row row_t;
row_t operator[](const int index)const{return *(result_[index]);}
</code></pre>
<p>Der Aufruf erklärt sich wie folgt:</p>
<pre><code class="language-cpp">result_t res = db-&gt;get_result();
std::string name=res[0][0];
</code></pre>
<p>res ist also vom typen dessen namen laut typedef result_t ist.<br />
mit [0] bekomm ich nun ein row objekt.<br />
Auf dieses wernde ich nun [0] an und bekomme dann das ergebnis aus dem<br />
vector bzw der map.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086074</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086074</guid><dc:creator><![CDATA[shapeless]]></dc:creator><pubDate>Mon, 26 Jun 2006 15:26:26 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 15:58:47 GMT]]></title><description><![CDATA[<blockquote>
<p>Und die const zurückgabe macht doch sinn</p>
</blockquote>
<p>neee, erstmal reden wir ueber eine Parameter uebergabe, ned zurueckgabe ^^</p>
<p>Im xxx(const int param) macht das const auch kein sinn, weil:<br />
wir sind bei c++ (hoffentlich) also macht der compiler von deinem param eine kopie. Diese kopie hat nen scope solange die funktion laeuft, und wird dann einfach weggeworfen. deinem aufrufendem programm isses also voellig wuerscht, was du innerhalb mit nem parameter machst, es bekommt davon soweiso nix mit, also kannst dir das const da auch sparen ^^</p>
<p>deine Rueckgabeparameter<br />
const std::string xyz();<br />
machen aber auch nich viel sinn ^^<br />
es gibt keinen grund, warum der zurueckgegebene string const sein soll!<br />
du bekommst ja (c++ !) ne kopie von irgendwas. Die intigritaet deiner Klasse schuetzt du damit nicht, weil dadurch das es ne kopie ist, deine klasse (also die instanz eher) ueberhaupt nicht davon beeinflusst wird.<br />
Und moderne kompiler sind intelligent genug da zu optimieren, so das dir das const auch keinen laufzeitvorteil bringt.</p>
<p>nen std::string test = myclass.xyz(); verhinderst du sowieso nich ^^</p>
<p>Dein bestreben, const sicher zu schreiben in ehren, aber an den stellen bringt es dir gar nix ^^</p>
<p>sinn wuerde es bei sowas machen:</p>
<p>const std::string &amp; get_irgendwas() const;</p>
<blockquote>
<p>row_t operator[](const int index)const{return *(result_[index]);}</p>
</blockquote>
<p>besser:</p>
<pre><code class="language-cpp">row_t operator[](unsigned int index)const{return *(result_[index]);}
</code></pre>
<p>oder hasst du negative indizies ? wenn du ne klasse wie ein array aufbauen willst sollt es sich auch an die Array Regeln halten ...</p>
<p>Ich sag nich das es falsch ist, es sieht nur komisch aus ^^</p>
<p>Aber zu deinem eigentlichen problem:</p>
<blockquote>
<p>result_t res = db-&gt;get_result();<br />
std::string name=res[0][0];</p>
</blockquote>
<p>schreib mal:<br />
result_t res = db-&gt;get_result();<br />
row_t myrow = res[0];<br />
std::string name = myrow[0];</p>
<p>und schau mal wo es da knallt ....</p>
<p>Ciao ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086089</guid><dc:creator><![CDATA[RHBaum]]></dc:creator><pubDate>Mon, 26 Jun 2006 15:58:47 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 16:17:32 GMT]]></title><description><![CDATA[<p>RHBaum schrieb:</p>
<blockquote>
<blockquote>
<p>Und die const zurückgabe macht doch sinn</p>
</blockquote>
<p>neee, erstmal reden wir ueber eine Parameter uebergabe, ned zurueckgabe ^^</p>
</blockquote>
<p>Japp meinte ich eigntlich auch -.-</p>
<p>RHBaum schrieb:</p>
<blockquote>
<p>Im xxx(const int param) macht das const auch kein sinn, weil:<br />
wir sind bei c++ (hoffentlich) also macht der compiler von deinem param eine kopie. Diese kopie hat nen scope solange die funktion laeuft, und wird dann einfach weggeworfen. deinem aufrufendem programm isses also voellig wuerscht, was du innerhalb mit nem parameter machst, es bekommt davon soweiso nix mit, also kannst dir das const da auch sparen ^^</p>
</blockquote>
<p>ACK</p>
<p>RHBaum schrieb:</p>
<blockquote>
<p>deine Rueckgabeparameter<br />
const std::string xyz();<br />
machen aber auch nich viel sinn ^^<br />
es gibt keinen grund, warum der zurueckgegebene string const sein soll!<br />
du bekommst ja (c++ !) ne kopie von irgendwas. Die intigritaet deiner Klasse schuetzt du damit nicht, weil dadurch das es ne kopie ist, deine klasse (also die instanz eher) ueberhaupt nicht davon beeinflusst wird.<br />
Und moderne kompiler sind intelligent genug da zu optimieren, so das dir das const auch keinen laufzeitvorteil bringt.</p>
</blockquote>
<p>ACK</p>
<p>RHBaum schrieb:</p>
<blockquote>
<p>nen std::string test = myclass.xyz(); verhinderst du sowieso nich ^^</p>
<p>Dein bestreben, const sicher zu schreiben in ehren, aber an den stellen bringt es dir gar nix ^^<br />
sinn wuerde es bei sowas machen:<br />
const std::string &amp; get_irgendwas() const;</p>
</blockquote>
<p>So war es mal, bevor ich lange zeit nach diesem Fehler suchen musste,<br />
und deswegen den code schon zerreissen musste und diverse male umgebaut habe,<br />
dennoch danke <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>RHBaum schrieb:</p>
<blockquote>
<p>Ich sag nich das es falsch ist, es sieht nur komisch aus ^^</p>
</blockquote>
<p>Japp, das stimmt schon, wie gesagt ich habs nicht wieder in den Urzustand<br />
gebracht, weil ich erst das Problem beheben will...</p>
<p>Aber zu deinem eigentlichen problem:</p>
<blockquote>
<p>result_t res = db-&gt;get_result();<br />
std::string name=res[0][0];</p>
<p>schreib mal:<br />
result_t res = db-&gt;get_result();<br />
row_t myrow = res[0];<br />
std::string name = myrow[0];</p>
</blockquote>
<p>Naja, wie erwartet, dass Gleiche wie vorher:<br />
( keine ahnung warum mein gcc manchmal deutsch spricht ... )</p>
<blockquote>
<p>example.cpp:36: Fehler: ISO C++ besagt, dass diese mehrdeutig sind, auch wenn die schlechteste Umwandlung für das erste besser ist als die schlechteste Umwandlung für das zweite:<br />
database_result.hpp:68: Anmerkung: Kandidat 1: const std::string&amp; libdb::db_row::operator[](int) const<br />
database_result.hpp:61: Anmerkung: Kandidat 2: const std::string&amp; libdb::db_row::operator[](const std::string&amp;)</p>
</blockquote>
<p>man bemerke :<br />
std::string name=row[&quot;user&quot;];<br />
funktioniert.</p>
<p>die genannte fehlerhafte Zeile macht folgendes (wie zuvor gesagt ):<br />
std::cout&lt;&lt;res[i][0]&lt;&lt;&quot;\n&quot;;<br />
//also kommt es beim benutzen von zahlen zur mehrdeutigkeit..<br />
oder wie du es wollest:<br />
row_t row=res[0];<br />
std::string name=row[0];<br />
//auch hier das Gleiche</p>
<p>achja: japp ich &quot;ha<strong>ss</strong>e&quot; negative indizies, habe aber natürlich keine=&gt;<br />
deshalb japp unsinged</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086111</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086111</guid><dc:creator><![CDATA[shapeless]]></dc:creator><pubDate>Mon, 26 Jun 2006 16:17:32 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 17:41:15 GMT]]></title><description><![CDATA[<p>offensichtlich sind hier implizite konvertierungen im spiel. schauen wir uns das noch einmal an:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

struct Foo
{
    std::string operator[](const std::string&amp;) { return &quot;string operator[](const string&amp;)&quot;; }
    std::string operator[](int) const { return &quot;string operator[](int) const&quot;; }
};

int main()
{
    Foo foo;
    std::cout &lt;&lt; foo[0];                         // mehrdeutig
    std::cout &lt;&lt; foo[(const char*)0];            // wählt die erste überladung
    std::cout &lt;&lt; const_cast&lt;const Foo&amp;&gt;(foo)[0]; // wählt die zweite überladung
}
</code></pre>
<p>ein konstanter integraler ausdruck mit dem wert 0 kann implizit in einen pointer umgewandelt werden (und std::string hat einen nicht expliziten ctor, der ein const char* nimmt). diese konvertierung hat schon viel kopfzerbrechen gekostet.<br />
was können wir nun tun, um die mehrdeutigkeit aufzulösen?<br />
offenbar würde es z.b. helfen, eine 3. nicht-const überladung, die ein int nimmt, zu haben - und so die konvertierung in const Foo&amp; zu vermeiden:</p>
<pre><code class="language-cpp">struct Foo
{
    std::string operator[](const std::string&amp;) { return &quot;string operator[](const string&amp;)&quot;; }
    std::string operator[](int arg)
    {
        // um duplizität zu vermeiden, könnten wir hjier die const variante aufrufen per
        // return const_cast&lt;const Foo&amp;&gt;(*this)[arg];
        return &quot;string operator[](int)&quot;;
    }
    std::string operator[](int) const { return &quot;string operator[](int) const&quot;; }
};
</code></pre>
<p>eine weitere variante wäre es, die implizite konvertierung in pointer zu unterdrücken. dazu müssen wir etwas tiefer in die trickkiste greifen: implizite konvertierungen finden nicht für argumente statt, deren typ durch typ deduktion ermittelt wurde. wir brauchen also ein template. um nun nicht mehr mmögliche argumenttypen als erlaubt zu haben, greifen wir auf SFINAE (hier mit boost::enable_if) zurück, um unerwünschte instantiierungen zu unterdrücken:</p>
<pre><code class="language-cpp">#include &quot;boost/utility/enable_if.hpp&quot;
#include &quot;boost/type_traits/is_same.hpp&quot;

struct Foo
{
    template&lt;typename T&gt;
    typename boost::enable_if_c
        &lt;
            boost::is_same&lt;std::string,T&gt;::value || boost::is_same&lt;const char*,T&gt;::value,
            std::string
        &gt;::type operator[](const T&amp;) { return &quot;template operator[]&quot;; }
    std::string operator[](int) const { return &quot;string operator[](int) const&quot;; }
};
</code></pre>
<p>das ist nat. schon ein bisschen heftiger und in diesem falle wohl mit kanonen auf spatzen geschossen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086199</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 26 Jun 2006 17:41:15 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfache operator[] überladung ist mehrdeutig on Mon, 26 Jun 2006 19:40:19 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>offensichtlich sind hier implizite konvertierungen im spiel. schauen wir uns das noch einmal an:</p>
</blockquote>
<p>Das dachte ich mir auch, aber ich dachte halt das es am int liegt,<br />
sprich, ich wusste nicht mehr ob der std::string c-tor der einen size_t bekommt,<br />
vorher als erstes nen char* argument haben muss.<br />
Aber das es an der 0 welche als const char* gesehen werden kann, darauf kam ich nicht.<br />
also danke erstmal für deine erklärung und beispiele.<br />
Die boost lösung find ich interessant und werd ich mir mal einfach so genauer anschaun, die mit dem nicht const operator werden ich dann wohl verwenden.<br />
leider kann ich das heute nicht mehr testen, aber ich gehe mal davon aus, dass<br />
es dann gehen sollte.<br />
Somit danke für die Hilfe, es hat mir echt richtig Kopfzerbrechen bereitet...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1086332</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1086332</guid><dc:creator><![CDATA[shapeless]]></dc:creator><pubDate>Mon, 26 Jun 2006 19:40:19 GMT</pubDate></item></channel></rss>