Template Class Problem

Started by
16 comments, last by nmi 18 years, 8 months ago
Does anyone see anything wrong with the following:

template <class T, T zero>
class CVector3
{
  private:
    T m_x, m_y, m_z;
  public:
    CVector3() : m_x(zero), m_y(zero), m_z(zero) {}
    CVector3(T x, T y, T z) : m_x(x), m_y(y), m_z(z) {}  
};

And using it...

CVector3<double, 0.0f> test;

I get the following error (using Dev-C++ w/ mingw 3.4.2)
Quote:42 `double' is not a valid type for a template constant parameter
I did a search on the net and couldnt find any information. Thanks, Sam
Advertisement
If you want to have a float or a double as a non-type template parameter, it has to be a reference to a float or double, not an actual float or double.
Hmmm... maybe I don't understand this correctly.


template <class T, T &zero>class CVector3{  private:    T m_x, m_y, m_z;  public:    CVector3() : m_x(zero), m_y(zero), m_z(zero) {}    CVector3(T x, T y, T z) : m_x(x), m_y(y), m_z(z) {}  };// SNIP    double d_zero = 0.0f;    CVector3<double, d_zero> yahoo;



This gives me the error:
`d_zero' cannot appear in a constant-expression
Only types, integers, bools, and function pointers can be template arguments. Floating point numbers can't. Sorry.
BTW: is there ever going to be a case where the "zero" element of a type used to specialize CVector3 will NOT be "0"?
I don't think there will ever be a time. It was more of an academic problem. I was looking through Data Structures for Game Programmers and saw how the author(s) were using this technique. They failed to mention that it doesnt work with floats or doubles :/
Quote:Original post by swinchen
I don't think there will ever be a time. It was more of an academic problem. I was looking through Data Structures for Game Programmers and saw how the author(s) were using this technique. They failed to mention that it doesnt work with floats or doubles :/


In that case, consider working with a single template parameter, and letting 'zero' be either a default-constructed T, or a T constructed with an argument of 0 (as a literal) - the latter will work for all numeric types plus everything that declares a constructor with that signature (one parameter of a type compatible with int).

template <class T>class CVector3{  private:    T m_x, m_y, m_z;  public:    CVector3() : m_x(T(0)), m_y(T(0)), m_z(T(0)) {}    // or just T() instead of T(0)    CVector3(T x, T y, T z) : m_x(x), m_y(y), m_z(z) {}  };// Or more simply:CVector3(T x = T(0), T y = T(0), T z = T(0)) : m_x(x), m_y(y), m_z(z) {}// provides both ctors, and two more probably-undesired ones
Quote:Original post by Sneftel
Only types, integers, bools, and function pointers can be template arguments. Floating point numbers can't. Sorry.


Nope. As I said, you can use references to floating point variables as a non-type parameter. Of course, you need to make sure that the variable has external linkage. Ex:
#include <iostream>template <float & f>class Fred {  public:    Fred() { std::cout << f << std::endl; }};float e = 2.818;int main(int, char **) {  Fred<e> a;  return 0;}
CVector3() : m_x(T()), m_y(T()), m_z(T()) {}

This should actually call the default ctor for all type T right? so assuming that T has a default ctor, and a copy operator this should work.

SiCrane, that method did not work for me...

template <class T, T &zero>
class CVector3
... snip ...

float temp = 0.0;
CVector3<float,temp> foo();

This gives me the error:
`d_zero' cannot appear in a constant-expression
Well, it could either be because your compiler doesn't fully support the C++ standard, or it could be because the variable doesn't have external linkage, or you could be passing a non-const reference in a place where the compiler expects a const value.

This topic is closed to new replies.

Advertisement