Static Template Member In Switch Statement

C

crjjrc

Hi. I've got a templated class Field<T>. The T ultimately resolves
to the various primitives like float and unsigned char. For each T I
know I will need, I define a static member variable inside Field whose
value is specific to the type. I define the constant for each type in
the definition file. The contents for the Field-related files are:

field.h
-------------------------------
#ifndef FIELD_H
#define FIELD_H

template<class T>
class Field {
public:
static const int moo;
};

#endif

field.cpp
-------------------------------
#include "field.h"
template<> const int Field<char>::moo = 7;


Okay, now when I try to reference this const member variables in a
switch statement, g++ gives me an error. The switch statement is
called from within a static function of another class, called
VolumeBase:

volumebase.h
-------------------------------
#include "field.h"

class VolumeBase {
public:
static void volfunc();
};

volumebase.cpp
-------------------------------
#include <iostream>
#include "volumebase.h"

void VolumeBase::volfunc() {

int val = 7;
switch (val) {
case Field<char>::moo:
std::cout << "in char" << std::endl;
break;
default:
std::cout << "failed" << std::endl;
break;
}

}


And when I try to compile all these...

$ g++ -c volumebase.cpp field.cpp
volumebase.cpp: In static member function `static void
VolumeBase::volfunc()':
volumebase.cpp:8: error: `Field<char>::moo' cannot appear in a
constant-expression

I would think that Field<char> could be resolved at this point and
that it would be constant, but this error message indicates that it is
not.

Any ideas? Help is appreciated.

- Chris
 
J

Junchen WANG

Hi. I've got a templated class Field<T>. The T ultimately resolves
to the various primitives like float and unsigned char. For each T I
know I will need, I define a static member variable inside Field whose
value is specific to the type. I define the constant for each type in
the definition file. The contents for the Field-related files are:

field.h
-------------------------------
#ifndef FIELD_H
#define FIELD_H

template<class T>
class Field {
public:
static const int moo;

};

#endif

field.cpp
-------------------------------
#include "field.h"
template<> const int Field<char>::moo = 7;

Okay, now when I try to reference this const member variables in a
switch statement, g++ gives me an error. The switch statement is
called from within a static function of another class, called
VolumeBase:

volumebase.h
-------------------------------
#include "field.h"

class VolumeBase {
public:
static void volfunc();

};

volumebase.cpp
-------------------------------
#include <iostream>
#include "volumebase.h"

void VolumeBase::volfunc() {

int val = 7;
switch (val) {
case Field<char>::moo:
std::cout << "in char" << std::endl;
break;
default:
std::cout << "failed" << std::endl;
break;
}

}

And when I try to compile all these...

$ g++ -c volumebase.cpp field.cpp
volumebase.cpp: In static member function `static void
VolumeBase::volfunc()':
volumebase.cpp:8: error: `Field<char>::moo' cannot appear in a
constant-expression

I would think that Field<char> could be resolved at this point and
that it would be constant, but this error message indicates that it is
not.

Any ideas? Help is appreciated.

- Chris

because Field<char>::moo is not a compiler-time constant. why not try
enumeration type ? Like this:

template<class T>
class Field {
public:
enum {CharMoo = 7, DoubleMoo};
};

and in the VolumeBase::volfunc, you can code like this:

void VolumeBase::volfunc() {


int val = 7;
switch (val) {
case Field<char>::CharMoo:
std::cout << "in char" << std::endl;
break;
default:
std::cout << "failed" << std::endl;
break;
}
}


Best Regards,
Junchen
 
M

Martin York

because Field<char>::moo is not a compiler-time constant. why not try
enumeration type ? Like this:

template<class T>
class Field {
public:
enum {CharMoo = 7, DoubleMoo};

};

and in the VolumeBase::volfunc, you can code like this:

void VolumeBase::volfunc() {

int val = 7;
switch (val) {
case Field<char>::CharMoo:
std::cout << "in char" << std::endl;
break;
default:
std::cout << "failed" << std::endl;
break;
}

}

Best Regards,
Junchen

As stated above moo is not a compile time constant.
An alternative implementation to that suggested above that maintains
the name moo for all classes:

#ifndef FIELD_H
#define FIELD_H

template<typename T>
struct FieldEnum
{};

template<>
struct FieldEnum<char>
{
enum {enumValue = 7};
};
template<>
struct FieldEnum<int>
{
enum {enumValue = 8};
};


template<typename T>
class Field {
public:
//static const int moo;
enum {moo = FieldEnum<T>::enumValue};

};

#endif
 
C

crjjrc

As stated above moo is not a compile time constant.
An alternative implementation to that suggested above that maintains
the name moo for all classes:
[...]

template<typename T>
struct FieldEnum
{};

template<>
struct FieldEnum<char>
{
enum {enumValue = 7};};
[...]

template<typename T>
class Field {
public:
//static const int moo;
enum {moo = FieldEnum<T>::enumValue};

I definitely would prefer this method, but it makes comparing
Field<char>::moo and Field<unsigned char>::moo require casting since
they are of different or anonymous types.

- Chris
 
C

crjjrc

because Field<char>::moo is not a compiler-time constant. why not try
enumeration type ? Like this:

template<class T>
class Field {
public:
enum {CharMoo = 7, DoubleMoo};

};

Thanks. I went with something like this, though I moved the enum to a
higher, untyped class so I didn't redundantly have to specify the type
(Field<char>::CharMoo).

- Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top