Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-type template parameter error ('x' is not a type)

Tags:

c++

gcc

g++

I am attempting to build an OS X version of my friend's QT application, which he has built on Windows and Linux. We are both using g++. I'm using gcc 4.2.1. Unfortunately I do not know what version he had used when he built the application (it was quite awhile ago).

Could anyone shed some light on why I am getting the error:

../../../src/dbapi/dbcore/node.h:24: error: 'dimensions' is not a type

when compiling the following code:

Node.h:

template<class T,const unsigned int dimensions>
class EXPORT_DBCORE Node : public Transform<T,dimensions>
{
public:
  Node( Id id,
        QString& name,
        QString& text = "",
        // ************** Offending line: ***************
        Vector<T,dimensions> position = Vector<T,dimensions>(),
        Quaternion<T> rotation = Quaternion<T>() )
    : Transform<T,dimensions>( position, rotation )
    , mId( id )
    , mName( name )
    , mText( text )
  {
  }

private:
  ...
};

Vector.h:

template<class T,const unsigned int dimensions>
class EXPORT_DBCORE Vector
{
public:
  //! Default Constructor
  Vector()
  {
    mpArray = new T[dimensions];
    for( int i = 0; i < dimensions; i++ )
    {
      mpArray[i] = 0;
    }
  }
...

Thanks.

EDIT: Sorry if it was not clear which line was number 24. It's indicated by the "Offending line" comment in the Node.h excerpt.

like image 796
Scott Stevenson Avatar asked Oct 05 '22 09:10

Scott Stevenson


1 Answers

Unfortunately I think the standard actually says this code is ill-formed, see core issue 325. The C++ grammar says that a comma in the template argument list for a default argument is parsed as starting the next function argument, so the problem is in the = Vector<T, dimensions>() bit of the code, so dimensions is taken as starting a new function parameter, not as part of the template-id.

GCC 4.4.0 was changed nearly five years ago (see Bug 57) to accept the code, do you have a good reason to be using such an old release?

If you can't upgrade, you can workaround the bug by adding a typedef to Node:

typedef Vector<T, dimensions> VectorType;

Then using that:

  Node( Id id,
        QString& name,
        QString& text = "",
        VectorType position = VectorType(),
        Quaternion<T> rotation = Quaternion<T>() )

Technically only the default argument needs to use the typedef, but I would use it for the parameter declaration and the default argument. In fact I almost always declare a typedef for any container type my classes use and then use that typedef in the class. That is often shorter and means if you change the container then you often only need to update the typedef, not every use of it.

like image 179
Jonathan Wakely Avatar answered Oct 10 '22 02:10

Jonathan Wakely