<?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[Vector range über binäre objekt grenzen]]></title><description><![CDATA[<p>Guten Tag,</p>
<p>also ich versuche einen weg zu finden um eine cevtor range (begin, end) über eine binäre grenze zu schaffen.</p>
<p>Also ich habe in einem shared object eine methode die in etwa diese signatur hat<br />
void bla(Object*, int numberOfObjects, int sizeOfObject);</p>
<p>Da die Shared lib mit mehreren Versionen von Object umgehen soll (also zb.):</p>
<pre><code>// V1
struct Object {
  int i;
}
</code></pre>
<pre><code>// V2
struct Object2 : public Object {
  int b;
}
</code></pre>
<p>fällt mir keine c++sigere Lösung ein als diese pointer frickelei mit der momentanen size des structs.<br />
So kann die shared lib mit allen objecten des structs aus V1 umgehen (somit halt auch mit allen nachfolgenden).</p>
<p>Ich hatte überlegt ob man dies mit CRTP irgendwie lösen kann, aber ich bin nicht zum durchbruch gekommen so das man die Shared lib auch mit neueren versionen verwenden kann.</p>
<p>Also die gewünschte funtionssignatur wäre sowas wie<br />
void bla(std::vector&lt;Object&gt;::iterator beg, std::vector&lt;Object&gt;::iterator end);<br />
oder was ähnlich c++siges :p</p>
<p>Hoffe ihr versteht mich..</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/340320/vector-range-über-binäre-objekt-grenzen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 05:38:37 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/340320.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 31 Oct 2016 13:46:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Mon, 31 Oct 2016 13:46:34 GMT]]></title><description><![CDATA[<p>Guten Tag,</p>
<p>also ich versuche einen weg zu finden um eine cevtor range (begin, end) über eine binäre grenze zu schaffen.</p>
<p>Also ich habe in einem shared object eine methode die in etwa diese signatur hat<br />
void bla(Object*, int numberOfObjects, int sizeOfObject);</p>
<p>Da die Shared lib mit mehreren Versionen von Object umgehen soll (also zb.):</p>
<pre><code>// V1
struct Object {
  int i;
}
</code></pre>
<pre><code>// V2
struct Object2 : public Object {
  int b;
}
</code></pre>
<p>fällt mir keine c++sigere Lösung ein als diese pointer frickelei mit der momentanen size des structs.<br />
So kann die shared lib mit allen objecten des structs aus V1 umgehen (somit halt auch mit allen nachfolgenden).</p>
<p>Ich hatte überlegt ob man dies mit CRTP irgendwie lösen kann, aber ich bin nicht zum durchbruch gekommen so das man die Shared lib auch mit neueren versionen verwenden kann.</p>
<p>Also die gewünschte funtionssignatur wäre sowas wie<br />
void bla(std::vector&lt;Object&gt;::iterator beg, std::vector&lt;Object&gt;::iterator end);<br />
oder was ähnlich c++siges :p</p>
<p>Hoffe ihr versteht mich..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513606</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513606</guid><dc:creator><![CDATA[fritz-cola]]></dc:creator><pubDate>Mon, 31 Oct 2016 13:46:34 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Mon, 31 Oct 2016 14:57:41 GMT]]></title><description><![CDATA[<p>fritz-cola schrieb:</p>
<blockquote>
<p>Also ich habe in einem shared object eine methode die in etwa diese signatur hat<br />
void bla(Object*, int numberOfObjects, int sizeOfObject);<br />
So kann die shared lib mit allen objecten des structs aus V1 umgehen (somit halt auch mit allen nachfolgenden).</p>
</blockquote>
<p>Das würde ich bezweifeln wollen, da Object und Object2 unterschiedlich groß sind. Du musst also schon in dem Bla-Code wissen, wie groß die sind. Wenn, dann bräuchtest du also ein Array auf Pointer, also Object**.</p>
<p>Kannst du nicht eine kleine Template-Funktion in den Header tun, die mit vector&lt;unique_ptr&lt;Object&gt;&gt; als auch mit vector&lt;unique_ptr&lt;Derived&gt;&gt; klarkommt? Diese kann ganz einfach bleiben und nur eine Library-Funktion aufrufen, die dann einfach ein Pointer auf Base nimmt.</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;vector&gt;
using namespace std;

// V1
struct Object {
    int i = 42;
};

// V2
struct Object2 : public Object {
    int b;
    Object2() { i = 23; }
};

void librayFunction(const Object *o) {
    cout &lt;&lt; o-&gt;i &lt;&lt; '\n';
}

template &lt;typename It&gt;
void bla2(It beg, It end)
{
    for (auto it = beg; it != end; ++it) librayFunction(it-&gt;get());
}

int main()
{
    vector&lt;unique_ptr&lt;Object&gt;&gt; vo1;
    vo1.push_back(make_unique&lt;Object&gt;());
    vo1.push_back(make_unique&lt;Object2&gt;());
    bla2(vo1.begin(), vo1.end());

    vector&lt;unique_ptr&lt;Object2&gt;&gt; vo2;
    vo2.push_back(make_unique&lt;Object2&gt;());
    bla2(vo2.begin(), vo2.end());
}
</code></pre>
<p>Disclaimer: kenne mich mit Binärgrezen nicht aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513623</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513623</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Mon, 31 Oct 2016 14:57:41 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Mon, 31 Oct 2016 15:14:51 GMT]]></title><description><![CDATA[<p>Moin,</p>
<p>danke erstmal für deine Antwort !</p>
<p>wob schrieb:</p>
<blockquote>
<p>fritz-cola schrieb:</p>
<blockquote>
<p>Also ich habe in einem shared object eine methode die in etwa diese signatur hat<br />
void bla(Object*, int numberOfObjects, int sizeOfObject);<br />
So kann die shared lib mit allen objecten des structs aus V1 umgehen (somit halt auch mit allen nachfolgenden).</p>
</blockquote>
<p>Das würde ich bezweifeln wollen, da Object und Object2 unterschiedlich groß sind. Du musst also schon in dem Bla-Code wissen, wie groß die sind. Wenn, dann bräuchtest du also ein Array auf Pointer, also Object**.</p>
</blockquote>
<p>Ne das funktioniert schon.. es ist halt mega hässlich. Es funktioniert weil bla weiß das sich in Object i befindet.. also kann bla mit i interagieren.<br />
Auch in V2 des structs befindet sich I an der stelle wie V1 so dass es da auch keine probleme gibt. Ist halt mega hässlich irgendwie :p</p>
<p>Also bla sieht ja wie folgt aus:</p>
<pre><code>bla(Object* obj, int numberOfObjects, int sizeOfObject) {
  int size = numberOfObjects * sizeOfObject;
  for (unsigned indexInfo= 0; indexInfo&lt; numberOfObjects; ++indexInfo) {
    Object *currentObj = reinterpret_cast&lt;Object*&gt;(reinterpret_cast&lt;char *&gt;(obj) + indexInfo * sizeOfObject);

    // do something with i from V1
  }
}
</code></pre>
<p>Und da das so mega hässlich und hacky ist, würde ich gerne etwas anderes benutzen... aber ich weiß halt echt nicht was man da machen kann</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513625</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513625</guid><dc:creator><![CDATA[fritz-cola]]></dc:creator><pubDate>Mon, 31 Oct 2016 15:14:51 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Wed, 02 Nov 2016 16:44:05 GMT]]></title><description><![CDATA[<p>wenns nur darum geht das is c++maessig aussieht, koenntest es z.b. so machen:</p>
<pre><code>// bissl helper code:
struct array_config
{
   array_config(base_object *t_arr, int t_count, int t_diff) : base_addr(t_arr), count(t_count), diff(t_diff) { }

   base_object *base_addr;
   int count;
   int diff;
};

template&lt;class T&gt;
inline auto config_array(T *arr, int t_count) -&gt; array_config
{
   return array_config(static_cast&lt;base_object*&gt;(arr), t_count, sizeof(T));
}

struct my_iter
{
   my_iter(const my_iter &amp;other) noexcept : addr(other.addr), diff(other.diff) { }
   my_iter(my_iter &amp;&amp;other) noexcept : addr(other.addr), diff(other.diff) { other.addr = nullptr; }
   my_iter(const array_config &amp;conf, bool is_end_it = false) : addr(conf.base_addr), diff(conf.diff) 
   { if(is_end_it == true) *reinterpret_cast&lt;char**&gt;(&amp;addr) += diff * conf.count; }

   auto operator=(const my_iter &amp;other) noexcept -&gt; my_iter&amp; { addr = other.addr; diff = other.diff; return *this; }
   auto operator=(my_iter &amp;&amp;other) noexcept -&gt; my_iter&amp; { addr = other.addr; diff = other.diff; other.addr = nullptr; return *this; }

   auto operator*(void) const noexcept -&gt; const base_object&amp; { return *addr; }
   auto operator*(void) noexcept -&gt; base_object&amp; { return *addr; }
   auto operator-&gt;(void) const noexcept -&gt; const base_object* { return addr; }
   auto operator-&gt;(void) noexcept -&gt; base_object* { return addr; }

   auto operator++(void) noexcept -&gt; my_iter&amp; 
   { 
      *reinterpret_cast&lt;char**&gt;(&amp;addr) += diff; 
      return *this; 
   }

   auto operator++(int) noexcept -&gt; my_iter { my_iter temp(*this); ++(*this); return temp; }

   base_object *addr;
   int diff;
};

auto operator==(const my_iter &amp;lhv, const my_iter &amp;rhv) noexcept -&gt; bool { return lhv.addr == rhv.addr; }
auto operator!=(const my_iter &amp;lhv, const my_iter &amp;rhv) noexcept -&gt; bool { return lhv.addr != rhv.addr; }
auto operator&lt;(const my_iter &amp;lhv, const my_iter &amp;rhv) noexcept -&gt; bool { return lhv.addr &lt; rhv.addr; }

auto begin(const array_config &amp;conf) noexcept -&gt; my_iter
{
   return my_iter(conf);
}

auto end(const array_config &amp;conf) noexcept -&gt; my_iter
{
   return my_iter(conf, true);
}

/* -------------------------------------------------------------------------- */
// jetzt deine klassen:
struct base_object
{
   base_object(void) : i(0) { }
   base_object(int ii) : i(ii) { }
   int i;
};

struct object : base_object
{
   object(void) : j(0) { }
   object(int jj) : base_object(jj + 1), j(jj) { }
   int j;
};

// nun die bla funktion, die mit dem array arbeiten soll:
auto bla(const array_config &amp;conf) -&gt; void
{
   for(auto const &amp;elem : conf)
   {
      std::cout &lt;&lt; elem.i &lt;&lt; &quot; &quot;;
   }

   std::cout &lt;&lt; std::endl;
}

// nun der aufruf von bla:
object obj[10];

   for(int i = 0;i &lt; 10; ++i)
   {
      obj[i].i = 12 + i;
      obj[i].j = 100 + i;
   }

   bla(config_array(obj, 10));
</code></pre>
<p>Ergebnis:</p>
<pre><code>12 13 14 15 16 17 18 19 20 21
</code></pre>
<p>Meep Meep</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513917</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513917</guid><dc:creator><![CDATA[Meep Meep]]></dc:creator><pubDate>Wed, 02 Nov 2016 16:44:05 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Wed, 02 Nov 2016 19:32:50 GMT]]></title><description><![CDATA[<p>Meep Meep schrieb:</p>
<blockquote>
<p>wenns nur darum geht das is c++maessig aussieht, koenntest es z.b. so machen:</p>
<pre><code>*reinterpret_cast&lt;char**&gt;(&amp;addr) += diff;
</code></pre>
</blockquote>
<p>Und wieso mit UB? Ist es wirklich so schwer, sich auf einen Zeigertyp festzulegen, and dass Ganze dann ohne verbotenes Aliasing durchzuziehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513930</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513930</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 02 Nov 2016 19:32:50 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Wed, 02 Nov 2016 20:04:55 GMT]]></title><description><![CDATA[<p>auf welchen zeigertyp wuerdest du dich da festlegen ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513933</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513933</guid><dc:creator><![CDATA[Meep Meep]]></dc:creator><pubDate>Wed, 02 Nov 2016 20:04:55 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Wed, 02 Nov 2016 20:17:11 GMT]]></title><description><![CDATA[<p>Meep Meep schrieb:</p>
<blockquote>
<p>auf welchen zeigertyp wuerdest du dich da festlegen ?</p>
</blockquote>
<p>base_object*, char* oder void* bieten sich an. Persönlich würde ich auch base_object* verwenden, aber konsequent:<br />
wenn es ein base_object* ist, darf es nicht als char* angefasst werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513934</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513934</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 02 Nov 2016 20:17:11 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Thu, 03 Nov 2016 03:42:16 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Meep Meep schrieb:</p>
<blockquote>
<p>auf welchen zeigertyp wuerdest du dich da festlegen ?</p>
</blockquote>
<p>base_object*, char* oder void* bieten sich an. Persönlich würde ich auch base_object* verwenden, aber konsequent:<br />
wenn es ein base_object* ist, darf es nicht als char* angefasst werden.</p>
</blockquote>
<p>ich caste ja nur nach char* um aufs byte genau den zeiger zu verschieben. schliesselich kann der versatz auch != eines vielfachen von sizeof(base_object) sein. ich war der meinung, das wenn es sich um pod-strukturen handelt, man das dann problemlos machen kann, wenn man den versatz richtig berechnet.<br />
sry die frage aber warum ist das dann UB ?</p>
<p>Meep Meep</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2513955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513955</guid><dc:creator><![CDATA[Meep Meep]]></dc:creator><pubDate>Thu, 03 Nov 2016 03:42:16 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Thu, 03 Nov 2016 09:50:57 GMT]]></title><description><![CDATA[<p>Meep Meep schrieb:</p>
<blockquote>
<p>sry die frage aber warum ist das dann UB ?</p>
</blockquote>
<p>Weil es die Aliasing-Regeln verletzt: du behandelst das Object addr, als ob es ein Objekt des Typs char* wäre.<br />
Das wäre in Ordnung:</p>
<pre><code class="language-cpp">addr = reinterpret_cast&lt;base_object*&gt;(reinterpret_cast&lt;char*&gt;(addr) + diff);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2513969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2513969</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 03 Nov 2016 09:50:57 GMT</pubDate></item><item><title><![CDATA[Reply to Vector range über binäre objekt grenzen on Fri, 04 Nov 2016 03:55:13 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Meep Meep schrieb:</p>
<blockquote>
<p>sry die frage aber warum ist das dann UB ?</p>
</blockquote>
<p>Weil es die Aliasing-Regeln verletzt: du behandelst das Object addr, als ob es ein Objekt des Typs char* wäre.<br />
Das wäre in Ordnung:</p>
<pre><code class="language-cpp">addr = reinterpret_cast&lt;base_object*&gt;(reinterpret_cast&lt;char*&gt;(addr) + diff);
</code></pre>
</blockquote>
<p>danke fuer die info zur aliasing regel. kannte die noch nicht.<br />
hab mir gerade nochmal ueberlegt wie es dazu kam das ich die zeile so geschrieben hab.<br />
urspruenglich hab ich geschrieben:</p>
<pre><code>reinterpret_cast&lt;char*&gt;(addr) += diff;
</code></pre>
<p>da bekam ich dann aber den fehler:</p>
<pre><code>error C2106: &quot;+=&quot;: Linker Operand muss ein L-Wert sein
</code></pre>
<p>aus dem grund hab ich das dann in</p>
<pre><code>*reinterpret_cast&lt;char**&gt;(&amp;addr) += diff;
</code></pre>
<p>geaendert, weil ich ehrlich gesagt zu faul war um nach dem fehler zu suchen.</p>
<p>Meep Meep</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2514036</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2514036</guid><dc:creator><![CDATA[Meep Meep]]></dc:creator><pubDate>Fri, 04 Nov 2016 03:55:13 GMT</pubDate></item></channel></rss>