<?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[Class template specialization: How to avoid code duplication?]]></title><description><![CDATA[<p>Hello!</p>
<p>Let us consider the following example:</p>
<pre><code class="language-cpp">template&lt;int N&gt; class C
{
  [...Members and methods...]
};

template&lt;&gt; class C&lt;0&gt;
{
  [...The same members and methods as in generic template...]

  C const &amp;NewMethod(void){return *this;}
};
</code></pre>
<p>Is there a possibility to avoid duplication of members and methods of the generic template in the specialized template?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/203397/class-template-specialization-how-to-avoid-code-duplication</link><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 14:02:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/203397.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 22 Jan 2008 12:42:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 13:49:07 GMT]]></title><description><![CDATA[<p>Hello!</p>
<p>Let us consider the following example:</p>
<pre><code class="language-cpp">template&lt;int N&gt; class C
{
  [...Members and methods...]
};

template&lt;&gt; class C&lt;0&gt;
{
  [...The same members and methods as in generic template...]

  C const &amp;NewMethod(void){return *this;}
};
</code></pre>
<p>Is there a possibility to avoid duplication of members and methods of the generic template in the specialized template?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441252</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441252</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 13:49:07 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 12:49:42 GMT]]></title><description><![CDATA[<p>yes, there is. (it's kind of a workaround, though)</p>
<p>use inheritance. for example: define a common base class with all the methods you need in every derived class. or build a class hierarchy which accomplishes exactly that.</p>
<p>(or, don't use specialization at all. after all, if the specialized class has the same interface as the generic one, it is difficult to speak of it as &quot;special&quot; - that is we don't know anything about your design. the more information about it, the more appropriate the solutions will be)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441255</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Tue, 22 Jan 2008 12:49:42 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 12:50:25 GMT]]></title><description><![CDATA[<p>You could put all shared members into a base class an inherit both your template and the specialization from it - so you only need to duplicate the constuctors of your class:</p>
<pre><code class="language-cpp">template&lt;int N&gt;
class C_base
{
  // shared members and methods
};

template&lt;int N&gt;
class C : public C_base&lt;N&gt;
{
  //here you only have to define your ctor's and redirect them to their C_base counterparts
};

template&lt;&gt;
class C&lt;0&gt; : public C_base&lt;0&gt;
{
  //again you need your ctor's here
  C const&amp; NewMethod() {return *this;}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1441256</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441256</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 22 Jan 2008 12:50:25 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 14:22:49 GMT]]></title><description><![CDATA[<p><em>you only need to duplicate the constuctors of your class</em><br />
I also <a href="http://www.cs.jcu.edu.au/Subjects/cp3120/1996/Lectures/c++/node92.html" rel="nofollow">need to duplicate operator=</a> and destructor (if I introduced some new members need to be destructed in the specialized class) <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>I think I cannot use the common base class for the following reason: I need these classes to simulate behaviour of the built-in type &quot;double&quot;. So, most of my methods are operators which return the value of the C class. If I write them in the C_base class then... what type it should receive and return ?</p>
<p>Here is more concrete example:</p>
<pre><code class="language-cpp">template&lt;int N&gt; class C
{
private:
  double x;
public:
  inline C(void): x(0.0) {;} //Default constructor
  inline C(double const x): x(x) {;} //Custom constructor

  inline C operator+(C const &amp;c) const {return C(x+c.x);}
  //... Other operators written in similar way
};

template&lt;&gt; class C&lt;0&gt;
{
  inline C(void): x(0.0) {;} //Default constructor
  inline C(double const x): x(x) {;} //Custom constructor

  inline C operator+(C const &amp;c) const {return C(x+c.x);} //operators are DUPLICATED
  //... Other operator written in similar way

  inline operator double(void) const {return x;} //New method
};
</code></pre>
<p>The problem is if I write</p>
<pre><code class="language-cpp">inline C operator+(C const &amp;c) const {return C(x+c.x);}
</code></pre>
<p>in the C_base class:</p>
<pre><code class="language-cpp">inline C_base operator+(C_base const &amp;c) const {return C_base(x+c.x);}
</code></pre>
<p>then it will return value that cannot be converted to double because the &quot;operator double&quot; is in the derived class C&lt;0&gt;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441298</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441298</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 14:22:49 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 13:54:28 GMT]]></title><description><![CDATA[<p>Are you sure you need a template for this case? Where in this class is the template parameter used?</p>
<p>(btw, many operator overloads can be supported as global functions, so you don't need to duplicate them for your specialzations)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441305</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441305</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 22 Jan 2008 13:54:28 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 14:19:24 GMT]]></title><description><![CDATA[<p>I have edited my previous post: added some additional text at the end.</p>
<p>I need template here to compile-time control dimensions of physical values (for example, meters):</p>
<p>Meters*Meters = Meters^2</p>
<p>So the following code should not compile:</p>
<pre><code class="language-cpp">typedef C&lt;1&gt; meters;
...
meters a;
a=a*a+a; //Physical-meaningless formula!
</code></pre>
<p>All is work for me now, but I am tired to simultaneosly modify 2 pieces of mostly similar code.</p>
<p>If I will not find something better, I will use #define <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441325</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441325</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 14:19:24 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 14:36:53 GMT]]></title><description><![CDATA[<p>First - nearly every operator can be used as a global method, so your class only needs a default ctor and an explicit ctor taking a double - and maybe some explicit value getter. operator= and copy-ctor can be generated by your compiler (your measure class doesn't have any members which need extra attantion).</p>
<p>Second - your base class could get some additional template parameters - just look out for &quot;mixin&quot;.</p>
<p>Third - maybe you take a look at <a href="http://www.boost.org/libs/mpl/doc/tutorial/dimensional-analysis.html" rel="nofollow">this page</a> - building physical values based on boost:mpl.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441335</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 22 Jan 2008 14:36:53 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 14:38:29 GMT]]></title><description><![CDATA[<p>as CStoll said, you could switch to global operators</p>
<p>//edit: too late.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441338</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Tue, 22 Jan 2008 14:38:29 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 15:47:10 GMT]]></title><description><![CDATA[<p>I don't see why it would be necessary to use any template specialization here:</p>
<pre><code class="language-cpp">template &lt;int m, int s, int kg&gt; class si
{
public:
    explicit si(double v = 0.0) :
        m_value(v)
    {}

    si operator +(si const&amp; other)
    { return si(m_value + other.m_value); }

    si operator -(si const&amp; other)
    { return si(m_value - other.m_value); }

    template &lt;int m2, int s2, int kg2&gt;
    si&lt;m + m2, s + s2, kg + kg2&gt; operator * (si&lt;m2, s2, kg2&gt; const&amp; other)
    { return si&lt;m + m2, s + s2, kg + kg2&gt;(m_value * other.m_value); }

    template &lt;int m2, int s2, int kg2&gt;
    si&lt;m - m2, s - s2, kg - kg2&gt; operator / (si&lt;m2, s2, kg2&gt; const&amp; other)
    { return si&lt;m - m2, s - s2, kg - kg2&gt;(m_value / other.m_value); }

    // ...
private:
    double m_value;
};

typedef si&lt;1, 0, 0&gt; meters;
typedef si&lt;0, 1, 0&gt; seconds;
typedef si&lt;0, 0, 1&gt; kilograms;
typedef si&lt;2, 0, 0&gt; square_meters;
typedef si&lt;1, -1, 0&gt; meters_per_second;
// ...

void foo()
{
    meters a(123);
    meters b(10);
    square_meters m2 = a * b;
}
</code></pre>
<p>Of course if you define an implicit ctor to allow conversion from a double, or an operator double to allow conversion to a double (or even both), then many implicit conversions will be possible even though they are &quot;unsafe&quot; (semantically).</p>
<p>The worst ones should be prohibited by the &quot;only one user-defined conversion&quot; rule, but if I needed a class like that I'd rather go without any implicit conversion at all.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441372</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441372</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 15:47:10 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 16:08:52 GMT]]></title><description><![CDATA[<p>The specialization is necessary because si&lt;0,0,0&gt; shold be equal to <code>double</code> , and others should not be equal. So, si&lt;0,0,0&gt; should have <code>operator double</code> , constructor from double and other members in addition to members that are already in <code>si&lt;a,b,c&gt;</code> , where a!=0, b!=0 or c!=0.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441396</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441396</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 16:08:52 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 17:29:47 GMT]]></title><description><![CDATA[<p>I will use global operators.</p>
<p>Thank you!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441473</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441473</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 17:29:47 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 17:59:39 GMT]]></title><description><![CDATA[<p>One thing you could do is explicitly disqualify si&lt;0,0,0&gt; (e.g. by adding a non-compilable specialisation for si&lt;0,0,0&gt;) and provide the &quot;normal&quot; templates with methods that yeld doubles for the special cases where all parameters would become 0, e.g.:</p>
<pre><code class="language-cpp">template &lt;int m, int s, int kg&gt; class si
{
public:
    explicit si(double v = 0.0);

 //Fundamental operators:
    si operator- () { return si(-m_value); }
    si&amp; operator+= (si const&amp; rhs) {m_value += rhs.m_value; };
    si&lt;-m,-s,-kg&gt; inverse() {return si&lt;-m,-s,-kg&gt;(1/m_value);}
 //Attention: operator*= only with double (others change dimensions)
    si&amp; operator*= (double rhs) {m_value *= rhs; };

 //Subtraction and division in terms of Addition and Multiplication:
    si&amp; operator-= (si const&amp; rhs) {*this += -rhs; };
    si&amp; operator/= (double rhs) {*this *= 1/rhs; };

 //Binary operators in terms of the unary ones above
    const si operator+ (si const&amp; rhs) { return si(*this) += rhs; }
    const si operator- (si const&amp; rhs) { return si(*this) -= rhs; }
    const si operator* (double rhs) { return si(*this) *= rhs; }
    const si operator/ (double rhs) { return si(*this) /= rhs; }

  //now, here goes the multiplication:
  const double operator*(si&lt;-m,-s,-kg&gt; const&amp; rhs) {return m_value*rhs.m_value;}

  template&lt;int m2, int s2, int kg2&gt;
  const si&lt;m+m2,s+s2,kg+kg2&gt; operator*(si&lt;m2,s2,kg2&gt; const&amp; rhs)
    {return si&lt;m+m2,s+s2,kg+kg2&gt;(m_value*rhs.m_value);}

  //division in terms of multiplication
  const double operator/(si&lt;m,s,kg&gt; const&amp; rhs) {return si(*this) * rhs.inverse(); }

  template&lt;int m2, int s2, int kg2&gt;
  const si&lt;m-m2,s-s2,kg-kg2&gt; operator*(si&lt;m2,s2,kg2&gt; const&amp; rhs)
    {return si(*this) * rhs.inverse();}

private:
    double m_value;
};

//multiplication and division with doubles from the left, 
template &lt;int m, int s, int kg&gt;
const si&lt;m,s,kg&gt; operator*(double lhs, si&lt;m,s,kg&gt; const&amp; rhs)
{ return rhs * lhs; }
template &lt;int m, int s, int kg&gt;
const si&lt;-m,-s,-kg&gt; operator/(double lhs, si&lt;m,s,kg&gt; const&amp; rhs)
{ return rhs.inverse() * lhs; }

template&lt;&gt; class si&lt;0,0,0&gt; {
  si();            //private, so no si&lt;0,0,0&gt;
  si(si const&amp;);   //can be instantiated
};
</code></pre>
<p>I hope I missed none. <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>As you see, there are four(!) binary operator*():</p>
<p>- two for left- and righthandside multiplication with scalars (double) that are implemented in terms of the unary one<br />
- one for multiplication with the inverse dimension (result is double)<br />
- one templated operator* for mutliplication with si's of other dimensions</p>
<p>This sample of operators should be fairly complete, and they are all implemented in terms of the following 6 functions:<br />
- operator-()<br />
- inverse()<br />
- operator*=(double)<br />
- operator+=(si&lt;dim&gt;)<br />
- double operator*(si&lt;dim&gt;, si&lt;-dim&gt;)<br />
- si&lt;dim1+dim2&gt; operator*(si&lt;dim1&gt;, si&lt;dim2&gt;)</p>
<p>/edit: the avoidance of si&lt;0,0,0&gt; avoids ambiguities such as this:</p>
<pre><code class="language-cpp">si&lt;0,0,0&gt; a(5.0);
double b = 4.0;
double c = a * b; //should the compiler use operator* (double, double) or operator*(si&lt;0,0,0&gt;, si&lt;0,0,0&gt;) ??
</code></pre>
<p>That's one of the reasons why you should be very, very, very, very careful (or even more very's) when providing implicit converions to and from other types</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441491</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441491</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 22 Jan 2008 17:59:39 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 18:11:24 GMT]]></title><description><![CDATA[<p>Tere is no need to specialise the whole template just for a few functions. Most of these can easily be dealt with using SFINAE - boost's enable_if applies here. This doesn't work with conversion operators however, so a different approach is needed: instead of giving one specialization that operators and all other specializations none, we can provide the conversion for each specialization but direct it to an undesirable type, when it's not needed, i.e.:</p>
<pre><code class="language-cpp">template &lt;int m, int s, int kg&gt; class si
{
    class dummy { Dummy(double) {} };
    typedef typename boost::mpl::if_c&lt;m==0&amp;&amp;s==0&amp;&amp;kg==0,double,Dummy&gt;::type conversion_target;
public:
...
    operator conversion_target() { return conversion_target(m_value); }
...
};
</code></pre>
<p>I dislike the naming scheme for being semantically unsound. meter cannot be more concrete than it already is, there is just one kind of meter, but you can have distinct objects of that class. if you mean length, measured in meters, the name should say so - obviously begging the question, what's so special about meter and why we can't measure in say milimeters as well (esp. considering that this kind of mechanical conversion really suits the computer better than us) - besides, the unit you use to measure in only matters when converting to or from a number, it's not relavant when operating with the quantities themselves. Either way, that discussion probably doesn't belong here.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441506</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441506</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 22 Jan 2008 18:11:24 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 20:19:03 GMT]]></title><description><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error" rel="nofollow">SFINAE</a>?<br />
Is it true???</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct can_use_f {
        typedef int type;
};

template&lt;&gt; struct can_use_f&lt;double&gt; {
};

template&lt;class T&gt; inline typename can_use_f&lt;T&gt;::type f(T a) {return a;}
</code></pre>
<p>After that I can not use f(10.2), but there is less-preferable conversion of 10.2 to int. I think I incorrectly understood SFINAE <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441584</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441584</guid><dc:creator><![CDATA[SAn]]></dc:creator><pubDate>Tue, 22 Jan 2008 20:19:03 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 21:15:54 GMT]]></title><description><![CDATA[<p>I really like campers version, I think you should go with that.</p>
<p>Or you could &quot;nuke&quot; the type si&lt;0, 0, 0&gt; alltogether, like pumuckl suggested, however I'd implement it differently.</p>
<p>Step 1 would be to add a STATIC_ASSERT(m != 0 || s != 0 || kg != 0), or spezialize the si&lt;0, 0, 0&gt; class to something completely unusable.<br />
Step 2 would be to write a type metafunction like this:</p>
<pre><code class="language-cpp">template &lt;int m, int kg, int s&gt; struct get_si_type
{
    typedef si&lt;m, kg, s&gt; type;
};

template &lt;&gt; struct get_si_type&lt;0, 0, 0&gt;
{
    typedef double type;
};
</code></pre>
<p>Then you can (Step 3) modify the si class like this:</p>
<pre><code class="language-cpp">template &lt;int m, int s, int kg&gt; class si
{
public:
    explicit si(double v = 0.0) :
        m_value(v)
    {}

    si operator +(si const&amp; other)
    { return si(m_value + other.m_value); }
    // ...

    template &lt;int m2, int s2, int kg2&gt;
    typename get_si_type&lt;m + m2, s + s2, kg + kg2&gt;::type operator * (si&lt;m2, s2, kg2&gt; const&amp; other) const
    { typedef typename get_si_type&lt;m + m2, s + s2, kg + kg2&gt;::type si_x;
      return si_x(m_value * other.m_value); }

    si operator * (double other) const
    { return si(m_value * other); }

    // ...
private:
    double m_value;
};
</code></pre>
<p>I think that might work. Although it might not be what you want, since it adds a little complexity to every template that want's to use an si type with computed template arguments (every such template would have to use get_si_type too, which micht cause some grief).</p>
<p>p.S.: in any case you should define the operators as free function, only I'm too lazy so I used member fn-s in my example-code.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441616</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441616</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 21:15:54 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 21:22:16 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>if you mean length, measured in meters, the name should say so - obviously begging the question, what's so special about meter and why we can't measure in say milimeters as well (esp. considering that this kind of mechanical conversion really suits the computer better than us)</p>
</blockquote>
<p>True, it should be length rather than meter, but there is something special about the meter: is the unit; magnitude prefixes are a different concept.</p>
<p>I kind of disagree with your parenthetical comment, though, or with the conclusion you want to draw from it anyway. The computer couldn't care less whether he's to calculate something in m or µm or lightyears. Thus it makes sense to simply scale input and output accordingly.</p>
<p>camper schrieb:</p>
<blockquote>
<p>- besides, the unit you use to measure in only matters when converting to or from a number, it's not relavant when operating with the quantities themselves. Either way, that discussion probably doesn't belong here.</p>
</blockquote>
<p>Probably I'm just failing to catch your drift here. But isn't that exactly the sole purpose of this class? To have type checking available for operations with the quantities?</p>
<p>By the by, there's no reason at all to say &quot;<a href="http://www.fallacyfiles.org/begquest.html" rel="nofollow">begging the question</a>&quot; when you actually mean &quot;raising the question&quot; <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1441620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441620</guid><dc:creator><![CDATA[finix]]></dc:creator><pubDate>Tue, 22 Jan 2008 21:22:16 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Tue, 22 Jan 2008 21:25:11 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Step 1 would be to add a STATIC_ASSERT(m != 0 || s != 0 || kg != 0), or spezialize the si&lt;0, 0, 0&gt; class to something completely unusable.</p>
</blockquote>
<p>Either that or make do with <code>typedef si&lt;0, 0, 0&gt; scalar;</code></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441622</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441622</guid><dc:creator><![CDATA[finix]]></dc:creator><pubDate>Tue, 22 Jan 2008 21:25:11 GMT</pubDate></item><item><title><![CDATA[Reply to Class template specialization: How to avoid code duplication? on Wed, 23 Jan 2008 08:45:48 GMT]]></title><description><![CDATA[<p>I had some more thoughts on this yesterday evening and I am still convinced that its is best to invalidate the si&lt;0,0,0&gt; case and let each operation return a double, that would give a scalar instead. I forgot to mention that the compiler prefers non-template methods before he considers instantiating a template, so in the example</p>
<pre><code class="language-cpp">si&lt;1,0,0&gt; fifteenmeters(15);
si&lt;1,-1,0&gt; fivemeterspersecond(5);
si&lt;0,1,0&gt; twoseconds(2);

double x = fifteenmeters / (fivemeterspersecond * twoseconds);
</code></pre>
<p>we get the following:</p>
<p>- fifteenmeterspersecond*twoseconds is done via the template operator* and gives an si&lt;1,0,0&gt;<br />
- the division of si&lt;1,0,0&gt;/si&lt;1,0,0&gt; matches the nontemplate operator/ that gives a double, so the compiler would not even try to instantiate the template operator that gives si&lt;0,0,0&gt; but just does the conversion for you by applying just the right operator.</p>
<p>One next step I thought of: In my example, an output operator is missing. How would you output something like si&lt;1,0,0&gt; (0.66e-11)? It depends, if you prefer meters or nanometers (thats 660 nanometers, if you have an application that deals with optics this would be the natural unit). And even defining a variable that holds this value doesn't look very nice and readable in your code. But consider the following:</p>
<pre><code class="language-cpp">//quantities
typedef si&lt;1,0,0&gt;  Length;
typedef si&lt;2,0,0&gt;  Area;
typedef si&lt;3,0,0&gt;  Volume;
typedef si&lt;1,-1,0&gt; Velocity;
typedef si&lt;1,-2,0&gt; Acceleration;
typedef si&lt;2,-2,1&gt; Energy;
/* ... */

//units
const Length meter = Length(1);
const Length centimeter = Length(0.01);
const Length nanometer = Length(1e-9);
const Length inch = Length(0.0254);
const Energy Joule = Energy(1);
const Volume litre = Volume(1e-3);
const Area hektar = Area(1e4);
const Energy GeV = Energy(1.602176462e-13);
/* ... */

//constants
const Acceleration ggrav = Acceleration(9.81);         //Earth surface acceleration
const si&lt;3,-2,-1&gt; GNewton = si&lt;3,-2,-1&gt;(6.67428e-11);  //Newtons gravitational constant
/* ... */
</code></pre>
<p>Looks like a lot of work, and it is. But calculations look like this:</p>
<pre><code class="language-cpp">//calculate the volume of a pyramid
int main() 
{
  Area base = 10 * centimeter * centimeter; // 10 cm²
  Length heigth = 15 * inch;  //15 inch
  Volume vPyramid = base * height / 3;

  cout &lt;&lt; &quot;The Volume is &quot; &lt;&lt; vPyramid / litre &lt;&lt; &quot; Litres\n&quot;
       &lt;&lt; &quot;That is &quot; &lt;&lt; vPyramid / (meter*meter*meter) &lt;&lt; &quot; cubic meters\n&quot;
       &lt;&lt; &quot;or &quot; &lt;&lt; vPyramid / (inch*inch*inch) &lt;&lt; &quot; cubic inches&quot; &lt;&lt; endl;
}
</code></pre>
<p>As you see, the operator&lt;&lt; does not need to be overloaded, its just doubles!</p>
<p>Looks much better than</p>
<pre><code class="language-cpp">//calculate the volume of a pyramid
int main() 
{
  si&lt;2,0,0&gt; base = si&lt;2,0,0&gt;(0.001);
  si&lt;1,0,0&gt; heigth = si&lt;1,0,0&gt;(15*0.0254);  //15 inch
  si&lt;3,0,0&gt; vPyramid = base * height / 3;

  cout &lt;&lt; &quot;The Volume is &quot; &lt;&lt; vPyramid &lt;&lt; &quot; in whatever Unit operator&lt;&lt; makes the output&quot;;
}
</code></pre>
<p>So, alltogether, you don't need error-prone implicit conversion operators to double if you convert automatically to doubles when its right, and you don't need to overload operator&lt;&lt; for the si&lt;&gt;'s if you provide the units and constants and even the code looks nice and readable.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441795</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441795</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 23 Jan 2008 08:45:48 GMT</pubDate></item></channel></rss>