<?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 specialisierungs problem &amp;amp;&amp;amp; function pointer]]></title><description><![CDATA[<p>Ich versuche folgendes <a href="http://doc.qt.nokia.com/4.6/qtendian.html#qFromBigEndian-2" rel="nofollow">http://doc.qt.nokia.com/4.6/qtendian.html#qFromBigEndian-2</a> (welches nur für q[u]int[16,32,64] definiert ist) zu wrappen (ich brauch das auch für q[u]int8 und float):</p>
<p>ERSTER VERSUCH:<br />
.h</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        if (sizeof(T) == 1)
        {
            return T(*src);
        }

        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        if (sizeof(T) == 1)
        {
            return T(*src);
        }

        return qFromBigEndian&lt;T&gt;(src);
    }

};
</code></pre>
<p>im .cpp</p>
<pre><code class="language-cpp">// char data[fileSize]; // filled with raw file data, (fixed mix of qint8, qint16, float and so on)
    // bool myEndianessLittle;      // true if on little endian system, else false 
    // bool dataEndianessLittle;    // true if data from file was saved using little endian

    if ( (myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) 
    {
        // no dataconversion needed
    }
    if ( (!myEndianessLittle) &amp;&amp; (!dataEndianessLittle) ) 
    {
        // no dataconversion needed
    }

    if ( (myEndianessLittle) &amp;&amp; (! dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::convertFromBigEndian&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromBigEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromBigEndian&lt;qint64&gt;;
         // usw.
    }

    if ( (! myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::convertFromLittleEndian&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromLittleEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromLittleEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromLittleEndian&lt;qint64&gt;;
         // usw.
    }
</code></pre>
<p>das kompiliert mit 4 Warnungen:</p>
<p>inline function 'T qFromLittleEndian(const uchar*) [with T = signed char]' used but never defined<br />
inline function 'T qFromLittleEndian(const uchar*) [with T = unsigned char]' used but never defined<br />
inline function 'T qFromBigEndian(const uchar*) [with T = signed char]' used but never defined<br />
inline function 'T qFromBigEndian(const uchar*) [with T = unsigned char]' used but never defined</p>
<p>ZWEITER VERSUCH</p>
<p>Das würde zwar nie gebraucht ( <code>sizeof(T)==1</code> ), da aber eklige Warnung dachte ich mir, füge ich Spezialisierungen hinzu:</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        return qFromBigEndian&lt;T&gt;(src);
    }

    template &lt;&gt;
    unsigned char convertFromLittleEndian&lt;unsigned char&gt;(const unsigned char * src)
    {
            return (*src);
    }

    template &lt;&gt;
    unsigned char convertFromBigEndian&lt;unsigned char&gt;(const unsigned char * src)
    {
            return (*src);
    }

};
</code></pre>
<p>Dann bekam:<br />
- explicit specialization in non-namespace scope 'class C3Dreader' (x2)<br />
- template-id 'convertFromLittleEndioan&lt;unsigned char&gt;' in declaration of primary template (x2)</p>
<p>DRITTER VERSUCH:<br />
also umgangen mit</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        return qFromBigEndian&lt;T&gt;(src);
    }

   template &lt;class T&gt;
    T  onlyConvert(const unsigned char * src)
    {
        return *((T*)(src));
    }
};
</code></pre>
<p>und im cpp</p>
<pre><code class="language-cpp">// char data[fileSize]; // filled with raw file data, (fixed mix of qint8, qint16, float and so on)
    // bool myEndianessLittle;      // true if on little endian system, else false 
    // bool dataEndianessLittle;    // true if data from file was saved using little endian

    if ( (myEndianessLittle) &amp;&amp; (dataEndianessLittle) ||  (!myEndianessLittle) &amp;&amp; (!dataEndianessLittle) ) 
    {
        // no dataconversion needed
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::onlyConvert&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::onlyConvert&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::onlyConvert&lt;qint64&gt;;
         // usw.
    }

    if ( (myEndianessLittle) &amp;&amp; (! dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromBigEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromBigEndian&lt;qint64&gt;;
         // usw.
    }

    if ( (! myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromLittleEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromLittleEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromLittleEndian&lt;qint64&gt;;
         // usw.
    }
</code></pre>
<p><strong>Das tut jetzt zwar so (compilieren mein ich) aber ich wüsste doch gerne was an der Spezialisierung falsch war?</strong></p>
<p>Wenn das tut wollte ich mir function pointer auf diese Methoden setzen:</p>
<p>in der .h</p>
<pre><code class="language-cpp">class C3Dreader {

public:
    // function pointer to function that convert from (unsigned)char to integer
    qint8       (C3Dreader::*getQINT8)      (const unsigned char*);
    qint16      (C3Dreader::*getQINT16)     (const unsigned char*);
    qint32      (C3Dreader::*getQINT32)     (const unsigned char*);
    qint64      (C3Dreader::*getQINT64)     (const unsigned char*);
    quint8      (C3Dreader::*getQUINT8)     (const unsigned char*);
    quint16     (C3Dreader::*getQUINT16)    (const unsigned char*);
    quint32     (C3Dreader::*getQUINT32)    (const unsigned char*);
    quint64     (C3Dreader::*getQUINT64)    (const unsigned char*);
    float       (C3Dreader::*getFLOAT)      (const unsigned char*); // &lt;&lt;-- aus nicht templatesierter methode
};
</code></pre>
<p>damit ich dann mit <code>getQINT8 (data[irgendwo])</code> einen qint8 davon kriege,<br />
mit den anderen entsprechend andere Datantypen.</p>
<p><strong>Mein Problem B: Hab ich auch noch nie gemacht, bin ich da schon dicht dran an der Syntax? Geht sowas überhaupt?</strong></p>
<p>Das hier compiliert, crasht aber bei der Ausführung immer:</p>
<pre><code class="language-cpp">C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;; 
char * h[4] = {0x0,0x0,0x21,0x0};
qint16 test = (*this-&gt;*getQINT16)((const unsigned char*)h[2]);
</code></pre>
<p>edit: typos</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/271608/template-specialisierungs-problem-amp-amp-function-pointer</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 11:19:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/271608.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 31 Jul 2010 18:50:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to template specialisierungs problem &amp;amp;&amp;amp; function pointer on Sat, 31 Jul 2010 21:32:58 GMT]]></title><description><![CDATA[<p>Ich versuche folgendes <a href="http://doc.qt.nokia.com/4.6/qtendian.html#qFromBigEndian-2" rel="nofollow">http://doc.qt.nokia.com/4.6/qtendian.html#qFromBigEndian-2</a> (welches nur für q[u]int[16,32,64] definiert ist) zu wrappen (ich brauch das auch für q[u]int8 und float):</p>
<p>ERSTER VERSUCH:<br />
.h</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        if (sizeof(T) == 1)
        {
            return T(*src);
        }

        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        if (sizeof(T) == 1)
        {
            return T(*src);
        }

        return qFromBigEndian&lt;T&gt;(src);
    }

};
</code></pre>
<p>im .cpp</p>
<pre><code class="language-cpp">// char data[fileSize]; // filled with raw file data, (fixed mix of qint8, qint16, float and so on)
    // bool myEndianessLittle;      // true if on little endian system, else false 
    // bool dataEndianessLittle;    // true if data from file was saved using little endian

    if ( (myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) 
    {
        // no dataconversion needed
    }
    if ( (!myEndianessLittle) &amp;&amp; (!dataEndianessLittle) ) 
    {
        // no dataconversion needed
    }

    if ( (myEndianessLittle) &amp;&amp; (! dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::convertFromBigEndian&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromBigEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromBigEndian&lt;qint64&gt;;
         // usw.
    }

    if ( (! myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::convertFromLittleEndian&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromLittleEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromLittleEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromLittleEndian&lt;qint64&gt;;
         // usw.
    }
</code></pre>
<p>das kompiliert mit 4 Warnungen:</p>
<p>inline function 'T qFromLittleEndian(const uchar*) [with T = signed char]' used but never defined<br />
inline function 'T qFromLittleEndian(const uchar*) [with T = unsigned char]' used but never defined<br />
inline function 'T qFromBigEndian(const uchar*) [with T = signed char]' used but never defined<br />
inline function 'T qFromBigEndian(const uchar*) [with T = unsigned char]' used but never defined</p>
<p>ZWEITER VERSUCH</p>
<p>Das würde zwar nie gebraucht ( <code>sizeof(T)==1</code> ), da aber eklige Warnung dachte ich mir, füge ich Spezialisierungen hinzu:</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        return qFromBigEndian&lt;T&gt;(src);
    }

    template &lt;&gt;
    unsigned char convertFromLittleEndian&lt;unsigned char&gt;(const unsigned char * src)
    {
            return (*src);
    }

    template &lt;&gt;
    unsigned char convertFromBigEndian&lt;unsigned char&gt;(const unsigned char * src)
    {
            return (*src);
    }

};
</code></pre>
<p>Dann bekam:<br />
- explicit specialization in non-namespace scope 'class C3Dreader' (x2)<br />
- template-id 'convertFromLittleEndioan&lt;unsigned char&gt;' in declaration of primary template (x2)</p>
<p>DRITTER VERSUCH:<br />
also umgangen mit</p>
<pre><code class="language-cpp">class C3Dreader {

 // unnötiges zeug gelöscht

   template &lt;class T&gt;
    T  convertFromLittleEndian(const unsigned char * src)
    {
        return qFromLittleEndian&lt;T&gt;(src);
    }

    template &lt;class T&gt;
    T  convertFromBigEndian(const unsigned char * src)
    {
        return qFromBigEndian&lt;T&gt;(src);
    }

   template &lt;class T&gt;
    T  onlyConvert(const unsigned char * src)
    {
        return *((T*)(src));
    }
};
</code></pre>
<p>und im cpp</p>
<pre><code class="language-cpp">// char data[fileSize]; // filled with raw file data, (fixed mix of qint8, qint16, float and so on)
    // bool myEndianessLittle;      // true if on little endian system, else false 
    // bool dataEndianessLittle;    // true if data from file was saved using little endian

    if ( (myEndianessLittle) &amp;&amp; (dataEndianessLittle) ||  (!myEndianessLittle) &amp;&amp; (!dataEndianessLittle) ) 
    {
        // no dataconversion needed
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::onlyConvert&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::onlyConvert&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::onlyConvert&lt;qint64&gt;;
         // usw.
    }

    if ( (myEndianessLittle) &amp;&amp; (! dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromBigEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromBigEndian&lt;qint64&gt;;
         // usw.
    }

    if ( (! myEndianessLittle) &amp;&amp; (dataEndianessLittle) ) // ~ 30% chance
    {
        C3Dreader::getQINT8     = &amp;C3Dreader::onlyConvert&lt;qint8&gt;;
        C3Dreader::getQINT16    = &amp;C3Dreader::convertFromLittleEndian&lt;qint16&gt;;
        C3Dreader::getQINT32    = &amp;C3Dreader::convertFromLittleEndian&lt;qint32&gt;;
        C3Dreader::getQINT64    = &amp;C3Dreader::convertFromLittleEndian&lt;qint64&gt;;
         // usw.
    }
</code></pre>
<p><strong>Das tut jetzt zwar so (compilieren mein ich) aber ich wüsste doch gerne was an der Spezialisierung falsch war?</strong></p>
<p>Wenn das tut wollte ich mir function pointer auf diese Methoden setzen:</p>
<p>in der .h</p>
<pre><code class="language-cpp">class C3Dreader {

public:
    // function pointer to function that convert from (unsigned)char to integer
    qint8       (C3Dreader::*getQINT8)      (const unsigned char*);
    qint16      (C3Dreader::*getQINT16)     (const unsigned char*);
    qint32      (C3Dreader::*getQINT32)     (const unsigned char*);
    qint64      (C3Dreader::*getQINT64)     (const unsigned char*);
    quint8      (C3Dreader::*getQUINT8)     (const unsigned char*);
    quint16     (C3Dreader::*getQUINT16)    (const unsigned char*);
    quint32     (C3Dreader::*getQUINT32)    (const unsigned char*);
    quint64     (C3Dreader::*getQUINT64)    (const unsigned char*);
    float       (C3Dreader::*getFLOAT)      (const unsigned char*); // &lt;&lt;-- aus nicht templatesierter methode
};
</code></pre>
<p>damit ich dann mit <code>getQINT8 (data[irgendwo])</code> einen qint8 davon kriege,<br />
mit den anderen entsprechend andere Datantypen.</p>
<p><strong>Mein Problem B: Hab ich auch noch nie gemacht, bin ich da schon dicht dran an der Syntax? Geht sowas überhaupt?</strong></p>
<p>Das hier compiliert, crasht aber bei der Ausführung immer:</p>
<pre><code class="language-cpp">C3Dreader::getQINT16    = &amp;C3Dreader::convertFromBigEndian&lt;qint16&gt;; 
char * h[4] = {0x0,0x0,0x21,0x0};
qint16 test = (*this-&gt;*getQINT16)((const unsigned char*)h[2]);
</code></pre>
<p>edit: typos</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1934528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1934528</guid><dc:creator><![CDATA[padreigh]]></dc:creator><pubDate>Sat, 31 Jul 2010 21:32:58 GMT</pubDate></item></channel></rss>