Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Starting with an <a href="http://sscce.org/" rel="nofollow">SSCCE</a>:</p> <pre><code>template&lt;typename T&gt; class Quaternion { }; template&lt;typename T&gt; class Vector3 { }; template&lt;typename T&gt; class Point3 { public: operator Vector3&lt;T&gt;() const { return Vector3&lt;T&gt;(); } friend Vector3&lt;T&gt; operator*( const Quaternion&lt;T&gt;&amp; lhs, const Vector3&lt;T&gt;&amp; rhs); }; template&lt;typename T&gt; Vector3&lt;T&gt; operator*(const Quaternion&lt;T&gt;&amp; lhs, const Vector3&lt;T&gt;&amp; rhs) { } int main() { Quaternion&lt;float&gt; orientation_; Point3&lt;float&gt; pt; Vector3&lt;float&gt; vec = orientation_*pt; return 0; } </code></pre> <p>Compiling that with gcc 4.7 I get the following:</p> <pre class="lang-none prettyprint-override"><code>x.cc:6:79: warning: friend declaration ‘Vector3&lt;T&gt; operator*(const Quaternion&lt;T&gt;&amp;, const Vector3&lt;T&gt;&amp;)’ declares a non-template function [-Wnon-template-friend] x.cc:6:79: note: (if this is not what you intended, make sure the function template has already been declared and add &lt;&gt; after the function name here) Undefined symbols for architecture x86_64: "operator*(Quaternion&lt;float&gt; const&amp;, Vector3&lt;float&gt; const&amp;)", referenced from: _main in ccKgI7Ru.o </code></pre> <p>This points out the problem: you are declaring a friend <em>function</em>, not a friend <em>template</em>. To fix this, you have to do two things: make sure the template declaration preceedes this friendship line, and add angle brackets:</p> <pre><code>template&lt;typename T&gt; Vector3&lt;T&gt; operator*(const Quaternion&lt;T&gt;&amp; lhs, const Vector3&lt;T&gt;&amp; rhs) { } template&lt;typename T&gt; class Point3 { public: operator Vector3&lt;T&gt;() const { return Vector3&lt;T&gt;(); } friend Vector3&lt;T&gt; operator*&lt;&gt;(const Quaternion&lt;T&gt;&amp; lhs, const Vector3&lt;T&gt;&amp; rhs); }; </code></pre> <p>This will turn the linker error into a compiler error:</p> <pre class="lang-none prettyprint-override"><code>error: no match for ‘operator*’ in ‘orientation_ * pt’ note: candidate is: note: template&lt;class T&gt; Vector3&lt;T&gt; operator*(const Quaternion&lt;T&gt;&amp;, const Vector3&lt;T&gt;&amp;) note: template argument deduction/substitution failed: note: ‘Point3&lt;float&gt;’ is not derived from ‘const Vector3&lt;T&gt;’ </code></pre> <p>Which makes sense: declaring a friend is a statement about who may access what data; it does not help a bit in automatic type conversions for template resolution. So I suggest the following instead:</p> <pre><code>template&lt;typename T&gt; class Point3 { public: operator Vector3&lt;T&gt;() const { return Vector3&lt;T&gt;(); } friend Vector3&lt;T&gt; operator*(const Quaternion&lt;T&gt;&amp; lhs, const Point3&amp; rhs) { return lhs * Vector3&lt;T&gt;(rhs); } }; </code></pre> <p>This declares a new inline friend operator, which will explicitely do the cast you had intended.</p>
 

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