Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I provide template specializations for typedefs of the same type?
    primarykey
    data
    text
    <p>A 3rd party SDK defines several typedefs, e.g.:</p> <pre><code>typedef unsigned char SDK_BYTE typedef double SDK_DOUBLE typedef unsigned char SDK_BOOLEAN </code></pre> <p>It also defines a variant type SdkVariant:</p> <pre><code>class SdkVariant { public: enum SdkType { SdkByte, SdkDouble, SdkBoolean }; bool toByte(SDK_BYTE&amp;); bool toDouble(SDK_DOUBLE&amp;); bool toBool(SDK_BOOLEAN&amp;); SdkType type(); }; </code></pre> <p>Retrieving a value from such a variant looks like this (presuming, we know the type of the contained value):</p> <pre><code>SdkVariant variant(foobar()); double value; bool res = variant.toDouble(value); if (!res) diePainfully(); else doSomethingWith(value); </code></pre> <p>This is quite verbose and therefore I want to provide a variant_cast-function-class that can perform the value retrieval and error handling:</p> <pre><code>// general interface: template&lt;class T&gt; class variant_cast { public: T operator()(const SdkVariant&amp; variant); }; // template specializations: template&lt;&gt; SDK_DOUBLE variant_cast&lt;SDK_DOUBLE&gt;::operator()(const SdkVariant&amp; variant) { SDK_DOUBLE value; bool res = variant.toDouble(value); if (!res) diePainfully(); return value; } template&lt;&gt; SDK_BYTE variant_cast&lt;SDK_BYTE&gt;::operator()(const SdkVariant&amp; variant) { SDK_BYTE value; bool res = variant.toByte(value); if (!res) diePainfully(); return value; } template&lt;&gt; SDK_BOOLEAN variant_cast&lt;SDK_BOOLEAN&gt;::operator()(const SdkVariant&amp; variant) { SDK_BOOLEAN value; bool res = variant.toByte(value); if (!res) diePainfully(); return value; } </code></pre> <p>This does not compile (C2995: Function template already defined), because SDK_BYTE and SDK_BOOLEAN are the same types (unsigned char). My idea is now to let the preprocessor check that SDK_BYTE and SDK_BOOLEAN are the same and if so, define a single template specialization for both. If they're different, it should use the two separate specializations from above. Like this:</p> <pre><code>#if SDK_BYTE == SDK_BOOLEAN template&lt;&gt; SDK_BYTE variant_cast&lt;SDK_BYTE&gt;::operator()(const SdkVariant&amp; variant) { SDK_BYTE value; bool res; if (variant.type() == SdkByte) res = variant.toByte(value); else res = variant.toBool(value); if (!res) diePainfully(); return value; } #else // code from above #endif </code></pre> <p>The problem with the above code is, that it appears to be impossible for the preprocessor to resolve the two typedefs. Is there a way to compare two typedefs (correctly) during preprocessing? If not, is there a way to hinder the compiler from resolving the typedefs, so that it would accept two different template specializations for SDK_BYTE and SDK_BOOLEAN? If not, I can still provide the single template specialization and use BOOST_STATIC_ASSERT to make the compiler fail if SDK_BYTE and SDK_BOOLEAN are unequal, but is there a better way to solve my problem?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload