Implicit conversion does not happen when I templatize

Here are a few related but different classes. One contains a list of floats; one contains only one. Sometimes I want, for example, to multiply them together. In this case, I want to “push” a list that is not a list to a list. Here's a code that works the way I want.

#define LIST_SZ 4 class Vec1; class Vec1_list { public: Vec1_list() {} Vec1_list(const Vec1& in); float x[LIST_SZ]; }; class Vec1 { public: Vec1() {} Vec1(const float& in); float x; }; Vec1::Vec1(const float& in) { x = in; } Vec1_list::Vec1_list(const Vec1& in) { for (int i = 0; i < LIST_SZ; i++) { x[i] = in.x; } } Vec1_list operator*(const Vec1_list& a, const Vec1_list& b) { Vec1_list tmp; for (int i = 0; i < LIST_SZ; i++) { tmp.x[i] = ax[i]*bx[i]; } return tmp; } int main(void) { Vec1 v1; Vec1_list v2, v3, answer; answer = v1*v3; } 

But now I’ll say that I want to plan it so that ...

 #define LIST_SZ 4 template <typename T> class Vec1; template <typename T> class Vec1_list { public: Vec1_list() {} Vec1_list(const Vec1<T>& in); T x[LIST_SZ]; }; template <typename T> class Vec1 { public: Vec1() {} Vec1(const T& in); T x; }; template <typename T> Vec1<T>::Vec1(const T& in) { x = in; } template <typename T> Vec1_list<T>::Vec1_list(const Vec1<T>& in) { for (int i = 0; i < LIST_SZ; i++) { x[i] = in.x; } } template <typename T> Vec1_list<T> operator*(const Vec1_list<T>& a, const Vec1_list<T>& b) { Vec1_list<T> tmp; for (int i = 0; i < LIST_SZ; i++) { tmp.x[i] = ax[i]*bx[i]; } return tmp; } int main(void) { Vec1<float> v1; Vec1_list<float> v2, v3, answer; answer = v1*v3; } 

"mult" forces the compiler to block this time - it will not automatically call my constructor Vec1 → Vec1_list. Is this a fact of life in C ++, or is there some method I can use to make this happen automatically? The alternative is that I need to have a huge fan of functions.

+4
source share
3 answers

You must declare operator* as a friend of the Vec1_list class Vec1_list that it is created when the Vec1_list , and then the conversion is performed.

EDIT: To do this, move the * operator definition to the declaration of the Vec1_list class template:

 friend static Vec1_list operator*(const Vec1_list& a, const Vec1_list& b){ /* ... */ } 
+1
source

Your user-defined transform using the transform constructor is not considered by subtracting the template argument.

The template output tries to find a replacement for the function template parameters that make the parameterized type identical to the argument types. When this is not possible, it is allowed (I simplify here): changing constant / volatile qualifications or converting a pointer based on "derived to base".

This is described in section 14.8.2.1/3 of the standard [temp.deduct.call].

+1
source

I do not know why this does not contribute to the desired Vec1_list . But if this is not possible, then you can always do this:

 template <typename T> Vec1_list<T> operator*(const Vec1<T>& a, const Vec1_list<T>& b) { return Vec1_list<T>(a)*b;; } 

By the way, I'm still digging the original issue.

0
source

All Articles