<?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[A good way to implement mutual conversion of user-defined classes?]]></title><description><![CDATA[<p>I have some user-defined classes:</p>
<pre><code class="language-cpp">class tMyType1{...};
class tMyType2{...};
class tMyType3{...};
class tMyType4{...};
class tMyType5{...};
</code></pre>
<p>And I need this classes to be converted to each other.</p>
<p>First of all, the conversion routines should take additional conversion parameters. So, they cannot be implemented as <code>operator=</code> . Another thing is that conversion is logically independent of classes implementation: classes should not know about each other. I decided to make conversion functions in the separate .h-file.</p>
<p><strong>So, I need your advice.</strong> What is a good practice for that?</p>
<p>I started to do this way:</p>
<pre><code class="language-cpp">//Conversion function template for the same types (5 conversions is one template):
template&lt;class T&gt; inline void Convert(T const &amp;vInput, T &amp;vOutput, int additionParameter)
{
  vOutput = vInput;
}

  //Conversions for different types (20 conversions):
inline void Convert(tMyType1 const &amp;vInput, tMyType2 &amp;vOutput, int additionParameter)
{
  ...
}

inline void Convert(tMyType1 const &amp;vInput, tMyType3 &amp;vOutput, int additionParameter)
{
  ...
}

...

inline void Convert(tMyType5 const &amp;vInput, tMyType4 &amp;vOutput, int additionParameter)
{
  ...
}
</code></pre>
<p>The problem is that I need to write implementation for 20 functions. But <em>in my case</em> the types <code>tMyType4</code> and <code>tMyType5</code> are very similar. The only difference is that <code>tMyType4</code> has <code>float</code> s inside, while <code>tMyType5</code> has <code>double</code> s. Therefore, the code for processing <code>tMyType4</code> and <code>tMyType5</code> values is identical. So, I need to write only 10 (not 20) different conversion functions.</p>
<p>But how to make this? I need to write something like that:</p>
<pre><code class="language-cpp">template&lt;class T = tMyType4 or tMyType5&gt; inline void Convert(tMyType1 const &amp;vInput, T &amp;vOutput)
{
  ...
}
</code></pre>
<p>Of course in that case I can write just this:</p>
<pre><code class="language-cpp">template&lt;class T&gt; inline void Convert(tMyType1 const &amp;vInput, T &amp;vOutput)
{
  ...
}
</code></pre>
<p>and hope that <code>T</code> is <code>tMyType4</code> or <code>tMyType5</code> . (I can add static assert for additional security), but what to do, if I will have <em>more than one</em> pair (or tripple) of almost-identical types?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/223848/a-good-way-to-implement-mutual-conversion-of-user-defined-classes</link><generator>RSS for Node</generator><lastBuildDate>Sat, 03 Oct 2026 12:53:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/223848.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 01 Oct 2008 18:19:57 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Wed, 01 Oct 2008 18:19:57 GMT]]></title><description><![CDATA[<p>I have some user-defined classes:</p>
<pre><code class="language-cpp">class tMyType1{...};
class tMyType2{...};
class tMyType3{...};
class tMyType4{...};
class tMyType5{...};
</code></pre>
<p>And I need this classes to be converted to each other.</p>
<p>First of all, the conversion routines should take additional conversion parameters. So, they cannot be implemented as <code>operator=</code> . Another thing is that conversion is logically independent of classes implementation: classes should not know about each other. I decided to make conversion functions in the separate .h-file.</p>
<p><strong>So, I need your advice.</strong> What is a good practice for that?</p>
<p>I started to do this way:</p>
<pre><code class="language-cpp">//Conversion function template for the same types (5 conversions is one template):
template&lt;class T&gt; inline void Convert(T const &amp;vInput, T &amp;vOutput, int additionParameter)
{
  vOutput = vInput;
}

  //Conversions for different types (20 conversions):
inline void Convert(tMyType1 const &amp;vInput, tMyType2 &amp;vOutput, int additionParameter)
{
  ...
}

inline void Convert(tMyType1 const &amp;vInput, tMyType3 &amp;vOutput, int additionParameter)
{
  ...
}

...

inline void Convert(tMyType5 const &amp;vInput, tMyType4 &amp;vOutput, int additionParameter)
{
  ...
}
</code></pre>
<p>The problem is that I need to write implementation for 20 functions. But <em>in my case</em> the types <code>tMyType4</code> and <code>tMyType5</code> are very similar. The only difference is that <code>tMyType4</code> has <code>float</code> s inside, while <code>tMyType5</code> has <code>double</code> s. Therefore, the code for processing <code>tMyType4</code> and <code>tMyType5</code> values is identical. So, I need to write only 10 (not 20) different conversion functions.</p>
<p>But how to make this? I need to write something like that:</p>
<pre><code class="language-cpp">template&lt;class T = tMyType4 or tMyType5&gt; inline void Convert(tMyType1 const &amp;vInput, T &amp;vOutput)
{
  ...
}
</code></pre>
<p>Of course in that case I can write just this:</p>
<pre><code class="language-cpp">template&lt;class T&gt; inline void Convert(tMyType1 const &amp;vInput, T &amp;vOutput)
{
  ...
}
</code></pre>
<p>and hope that <code>T</code> is <code>tMyType4</code> or <code>tMyType5</code> . (I can add static assert for additional security), but what to do, if I will have <em>more than one</em> pair (or tripple) of almost-identical types?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591681</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Wed, 01 Oct 2008 18:19:57 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Wed, 01 Oct 2008 18:45:44 GMT]]></title><description><![CDATA[<p>boost::enable_if&lt;&gt;<br />
would work.</p>
<p>But I think you are doing something wrong.</p>
<p>All these classes need to have something in common - otherwise a conversation won't make much sense... Often it is possible to implement all conversations based on a generic interface. For example, you said some classes use float, some uses double. That's the same Code. But what do the others use? int? string? etc. All can be converted easily with some simple helper functions like boost::lexical_cast&lt;&gt;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591697</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591697</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 01 Oct 2008 18:45:44 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Wed, 01 Oct 2008 19:22:16 GMT]]></title><description><![CDATA[<p>You can write &quot;read&quot; and &quot;write&quot; methods for each class to de/serialize them as XML (or some simpler format), then you can save one class as XML and load another from this XML.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591720</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591720</guid><dc:creator><![CDATA[Klusiparqua]]></dc:creator><pubDate>Wed, 01 Oct 2008 19:22:16 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Wed, 01 Oct 2008 21:37:53 GMT]]></title><description><![CDATA[<p>I'd like to know what those types are. Without that knowledge one can only speculate as to what would be the best way to do things.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591770</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591770</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 01 Oct 2008 21:37:53 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Mon, 06 Oct 2008 06:31:18 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>... conversation ...</p>
</blockquote>
<p>Pretty sure you meant conversions? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> Besides, I totally agree.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591841</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591841</guid><dc:creator><![CDATA[7H3 N4C3R]]></dc:creator><pubDate>Mon, 06 Oct 2008 06:31:18 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 09:26:18 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>I'd like to know what those types are. Without that knowledge one can only speculate as to what would be the best way to do things.</p>
</blockquote>
<p>You are right. I need to convert colors from one color space to another. This needs to be done very fast.</p>
<p>Color is something like that:</p>
<pre><code class="language-cpp">template&lt;idColorFormat CF, idColorComponentType CT&gt; struct tColor;
</code></pre>
<p><code>idColorFormat</code> is something like <code>cfRGB</code> , <code>cfBGR</code> , <code>cfGrayscale</code> , <code>cfIndexed</code> .<br />
<code>idColorComponentType</code> is something like <code>ctUChar</code> , <code>ctUShort</code> , <code>ctUInt</code> , <code>ctFloat</code> , <code>ctDouble</code> .</p>
<p>I have already done all possible conversions of colors from one pair of parameters <code>&lt;CF,CT&gt;</code> to any other pair. The idea is that <code>tColor</code> contain 3 or 1 components inside:</p>
<pre><code class="language-cpp">template&lt;idColorComponentType CT&gt; tColorComponent;

template&lt;idColorComponentType CT&gt; tColor&lt;cfRGB,CT&gt;
{
  tColorComponent&lt;CT&gt; r,g,b;
  ...
};
</code></pre>
<p>So, the conversion operators of <code>tColor</code> deal with different <code>idColorFormat</code> , while <code>tColorComponent</code> deal with different <code>idColorComponentType</code> .</p>
<p>So (if omit <code>cfIndexed</code> ), I need (3*3-3)+(5*5-5) = 6+20 conversion operators. And I have done this.</p>
<p>The problem is that I need to go further, and make <em>color space</em> conversion. I decided to use ONLY <code>cfRGB</code> color format for such conversions. Color space is something like that:</p>
<pre><code class="language-cpp">enum idColorSpace{csCIEXYZ,    //CIE 1931 XYZ color space. X,Y,Z values are stored in R,G,B respectively
                  csSRGBLinear, //sRGB Linear color space
                  csSRGB,      //sRGB color space
                  csCIELAB};  //CIE 1976 LAB color space. L,A,B values are stored in G,R,B respectively

template&lt;idColorSpace T&gt; struct tColorSpace{}; //To store idColorSpace as compile-time constant to use function overloading instead of template specialization.
</code></pre>
<p>I think conversion functions should look like that:</p>
<pre><code class="language-cpp">template&lt;idColorComponentType CT1, idColorComponentType CT2, idColorSpace CS1, idColorSpace CS2&gt;
  inline void ConvertColor(tColor&lt;cfRGB,CT1&gt; const &amp;c1, tColor&lt;cfRGB,CT2&gt; &amp;c2, tColorSpace&lt;CS1&gt;, tColorSpace&lt;CS2&gt;, bool clip);
</code></pre>
<p>Notice that I perform color space conversion at the same time as color component type conversion. This is very important to be able to do some optimizations (such as using of tables).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591967</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591967</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Thu, 02 Oct 2008 09:26:18 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 09:36:37 GMT]]></title><description><![CDATA[<p>SAn schrieb:</p>
<blockquote>
<p>But how to make this? I need to write something like that:</p>
<pre><code class="language-cpp">template&lt;class T = tMyType4 or tMyType5&gt; inline void Convert(tMyType1 const &amp;vInput, T &amp;vOutput)
{ ... }
</code></pre>
</blockquote>
<p>you could use a traits-template (like std::iterator_traits).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591976</guid><dc:creator><![CDATA[wandrer]]></dc:creator><pubDate>Thu, 02 Oct 2008 09:36:37 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 09:51:11 GMT]]></title><description><![CDATA[<p>example:</p>
<pre><code class="language-cpp">class CA {};
class CB {};
class CC {};
class CD {};
class CE {};

namespace hidden
{
	struct float_cat {};
	struct other_cat {};

	// assign categories (concepts) to the userdefined classes
	template &lt; class T &gt; struct traits {};
	template &lt;&gt; struct traits&lt;CA&gt; { typedef other_cat cat; };
	template &lt;&gt; struct traits&lt;CB&gt; { typedef other_cat cat; }; 
	template &lt;&gt; struct traits&lt;CC&gt; { typedef other_cat cat; }; 
	template &lt;&gt; struct traits&lt;CD&gt; { typedef float_cat cat; }; 
	template &lt;&gt; struct traits&lt;CE&gt; { typedef float_cat cat; };

	template &lt; class A, class B, class CAT &gt; void convert( A const &amp;a, B &amp;b, CAT c );

	// specialized template-instances for category float_cat ...
	template &lt; class B &gt; void convert( CA const &amp;a, B &amp;b, float_cat c ) { TEST; }
	template &lt; class B &gt; void convert( CB const &amp;a, B &amp;b, float_cat c ) { TEST; }
	template &lt; class B &gt; void convert( CC const &amp;a, B &amp;b, float_cat c ) { TEST; }

	// ...and other_cat
	void convert( CA const &amp;a, CB &amp;b, other_cat c ) { TEST; }
	void convert( CA const &amp;a, CC &amp;b, other_cat c ) { TEST; }

	/*...*/
}

template &lt; class T &gt; void convert( T const&amp; a, T &amp;b ) { b = a; }

// call the right function by passing a dummy-instance of type traits::cat
template &lt; class A, class B &gt; void convert( A const&amp; a, B &amp;b )
{ hidden::convert( a, b, typename hidden::traits&lt;B&gt;::cat() ); }
</code></pre>
<p>man verzeihe mein englisch...<br />
... und dass ich tatsächlich 5 klassen deklariert hab...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1591987</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1591987</guid><dc:creator><![CDATA[wandrer]]></dc:creator><pubDate>Thu, 02 Oct 2008 09:51:11 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 13:51:31 GMT]]></title><description><![CDATA[<p>I don't have much time to think about this right now, but you could have a look at GIL:<br />
<a href="http://www.boost.org/doc/libs/1_36_0/libs/gil/doc/index.html" rel="nofollow">http://www.boost.org/doc/libs/1_36_0/libs/gil/doc/index.html</a></p>
<p>Maybe you could use it directly, or maybe you find some clever idea in there that you could borrow <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1592200</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1592200</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 02 Oct 2008 13:51:31 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 14:59:58 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>I don't have much time to think about this right now, but you could have a look at GIL:<br />
<a href="http://www.boost.org/doc/libs/1_36_0/libs/gil/doc/index.html" rel="nofollow">http://www.boost.org/doc/libs/1_36_0/libs/gil/doc/index.html</a></p>
<p>Maybe you could use it directly, or maybe you find some clever idea in there that you could borrow <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Very interesting! In fact, I'm not familiar with Boost, Iterators and other such things. So, I need something simplier. But I will look at color conversion there...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1592264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1592264</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Thu, 02 Oct 2008 14:59:58 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 18:33:09 GMT]]></title><description><![CDATA[<p>Do you have one instance of your class per pixel? I think this will be much overhead.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1592410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1592410</guid><dc:creator><![CDATA[asdfgfvsd]]></dc:creator><pubDate>Thu, 02 Oct 2008 18:33:09 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Thu, 02 Oct 2008 19:16:24 GMT]]></title><description><![CDATA[<p>asdfgfvsd schrieb:</p>
<blockquote>
<p>Do you have one instance of your class per pixel? I think this will be much overhead.</p>
</blockquote>
<p>C++ classes do not have any overhead in particular compared to C-structs or plain old data types. They are more or less syntactic sugar, if you do not use (dynamic) polymorphism. The compiler takes care of optimizations. I think this is called the &quot;zero cost&quot; principle of C++.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1592445</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1592445</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Thu, 02 Oct 2008 19:16:24 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Fri, 03 Oct 2008 05:37:28 GMT]]></title><description><![CDATA[<p>I think normally int or float arrays are used to represent the pixels of an image. I have never seen an array of classes to store pixles.<br />
Will this have the same speed?</p>
<pre><code class="language-cpp">std::vector&lt;int&gt; pixels;
...
for(...)
     pixels[pos+0] = r;
     pixels[pos+1] = g;
     pixels[pos+2] = b;

std::vector&lt;PixelClass&gt; pixels;
...
for(...)
     pixels[pos].r = r;
     pixels[pos].g = g;
     pixels[pos].b = b;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1592699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1592699</guid><dc:creator><![CDATA[asdfgfvsd]]></dc:creator><pubDate>Fri, 03 Oct 2008 05:37:28 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Fri, 03 Oct 2008 17:39:01 GMT]]></title><description><![CDATA[<blockquote>
<p>Will this have the same speed?</p>
</blockquote>
<p>Nothing is ever the same.<br />
But both solutions should be close.</p>
<p>It all depends on what the compiler will optimize better, and of course on what alignment the compiler will be using for the RGB-struct. And probably a dozen other little things.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1593077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1593077</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 03 Oct 2008 17:39:01 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Fri, 03 Oct 2008 19:37:32 GMT]]></title><description><![CDATA[<p>wandrer schrieb:</p>
<blockquote>
<p>example:</p>
<p>[...]</p>
<p>man verzeihe mein englisch...<br />
... und dass ich tatsächlich 5 klassen deklariert hab...</p>
</blockquote>
<p>Thank you! This is exactly what I need.</p>
<p>In fact, I already have traits of 3 types in my libriary:</p>
<pre><code class="language-cpp">enum idColorComponentFamily { ccfUnsignedInteger, ccfSignedInteger, ccfFloatingPoint };
</code></pre>
<p>I just could't figure out how to use that until I have seen your example.</p>
<p>Now I will do that way: <code>ccfUnsignedInteger</code>  — depend of type, <code>ccfSignedInteger</code>  — forbidden, because signed integers are special cases, <code>ccfFloatingPoint</code>  — use the same algorithm for both <code>float</code> and <code>double</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1593127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1593127</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Fri, 03 Oct 2008 19:37:32 GMT</pubDate></item><item><title><![CDATA[Reply to A good way to implement mutual conversion of user-defined classes? on Fri, 03 Oct 2008 19:35:35 GMT]]></title><description><![CDATA[<p>asdfgfvsd schrieb:</p>
<blockquote>
<p>I think normally int or float arrays are used to represent the pixels of an image. I have never seen an array of classes to store pixles.<br />
Will this have the same speed?</p>
<pre><code class="language-cpp">std::vector&lt;int&gt; pixels;
...
for(...)
     pixels[pos+0] = r;
     pixels[pos+1] = g;
     pixels[pos+2] = b;

std::vector&lt;PixelClass&gt; pixels;
...
for(...)
     pixels[pos].r = r;
     pixels[pos].g = g;
     pixels[pos].b = b;
</code></pre>
</blockquote>
<p>Yes, this will have the same speed for most cases.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1593130</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1593130</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Fri, 03 Oct 2008 19:35:35 GMT</pubDate></item></channel></rss>