c++ vector swizzling cont'd

Hi,

I got a little stuck while implementing vector swizzling. I tried to templatize the vector classes so that it can be based on float, double, int etc. However this was the functions declared outside the class don't accept the swizzle types. It seems like no conversion happens.

Here's the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
template< typename t >
class vec2i
{
  private:
    template< int a, int b, int c, int d >
    class swizzle
    {
      private:
        t v[2];
      public:
        operator vec2i()
        {
          return vec2i( v[a], v[b] );
        }
    };
  public:
    union
    {
      struct
      {
        t x, y;
      };

      swizzle < 0, 1, -2, -3 > xy;

      t v[2];
    };

    vec2i( const t& a, const t& b ) : x( a ), y( b ) {}
    explicit vec2i( const t& num ) : x( num ), y( num ) {}
    vec2i() : x( 0 ), y( 0 ) {}
};

typedef vec2i<float> vec2;
typedef vec2i<double> dvec2;

template< typename t >
vec2i<t> operator+ ( const vec2i<t>& a, const vec2i<t>& b )
{
  return vec2i<t>( a.x + b.x, a.y + b.y );
}

int main( int argc, char** argv )
{
  vec2 a( 1, 2 );

  a = a + a.xy; //generates no operator + found, saying candidate is the operator+ func

  return 0;
}


it generates this error:

main.cpp:47:13: error: no match for ‘operator+’ in ‘a + a.vec2i<float>::<anonymous>.vec2i<float>::<anonymous union>::xy’
main.cpp:47:13: note: candidate is:
main.cpp:38:10: note: template<class t> vec2i<t> operator+(const vec2i<t>&, const vec2i<t>&)


Why does no conversion happen, and how can I solve this?
Last edited on
well, you didn't define an operator for xy (which has the type float in this case):

1
2
template< typename t >
vec2i<t> operator+ ( const vec2i<t>& a, const t b )
that doesn't work. Doesn't xy have the type swizzle<0, 1, -2, -3>?

EDIT: btw this works, but I don't want to define a function for all types. So how do I get around this?
1
2
3
4
vec2 operator+ ( const vec2& a, const vec2& b )
{
  return vec2( a.x + b.x, a.y + b.y );
}
Last edited on
closed account (o1vk4iN6)
You can't use implicit type conversion and also use templates.

1
2
3
4
5
6
7
8

//this will work
template< typename t >
vec2i<t> operator+ ( const vec2i<t>& a,  const vec2i<float>& b )
{
  return vec2i<t>( a.x + b.x, a.y + b.y );
}


it isn't able to use the implicit type conversion because it has to determine the type.

If you move the operator into the class definition, it will now know what type b has to be so the implicit conversion will follow through.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

template< typename t >
class vec2i
{
	/* ... */

	vec2i operator+( const vec2i & b)
	{
		return vec2i( this->x + b.x, this->y + b.y );
	}

	/* ... */

};



The samething will happen in this case:

1
2
3
4
5
6
7
8
9
10

template<class T>
void func( T a, T b )
{
}

func( 1.0f, 1 ); // error, as "1" is int and it can't be implicitly converted to float in this case as it's being used to identify "T"

func<float>( 1.0f, 1 ); // good, known type is float and 1 is converted to float
Last edited on
that seems to work :)
but I have functions that must be declared outside the class, because they have to be called like this
func(vec_a, vec_b);
and not like
vec_a.func(vec_b);
how can I solve those cases?
closed account (o1vk4iN6)
Either have to take a swizzle as a parameter or when you pass it you need to explicitly cast it to vec2.
hmmm ok, this is going to be tedious, but at least it will work :)
Topic archived. No new replies allowed.