Const int passed to a templated method

Angelo Calafato angelo.calafato@gmail.com
Thu Sep 28 10:41:00 GMT 2006


Hello everybody,
I am new to this mailing list so I want to say hello to all the members to this
precious mailing list. I am trying to understand traits and template
metaprogramming. My goal is to avoid inheritance to select a particular
member method at compile-time based on a parameter passed to the
constructor. I don't understand why i couldn't pass a constant int to a
template function in a class member while this is allowed in the main().
The error that gcc returns is:

error: 'Display::_t' cannot appear in a constant-expression
error: template argument 1 is invalid
error: invalid type in declaration before ';' token

I provide two lists, a version of my sample code unsing inheritance and
the templated version that gave me this prboblem.

Thank in advance for every help or suggestions.

//-------------------------------------------------
// INHERITANCE VERSION
//-------------------------------------------------
#include <iostream>

class Display
{
public:
    static const int TYPE1;
    static const int TYPE2;

    Display(const int& t) : _t(t) {}
    virtual void process() {}
private:
    const int _t;
};
const int Display::TYPE1 = 1;
const int Display::TYPE2 = 2;

class DisplayType1 : public Display {
public:
    DisplayType1() : Display(Display::TYPE1) {}
    void process() { std::cout << "Type1\n"; }
};

class DisplayType2 : public Display {
public:
    DisplayType2() : Display(Display::TYPE2) {}
    void process() { std::cout << "Type2\n"; }
};

void f(Display& d) { d.process(); }

int main() {
    DisplayType1 dt1;
    DisplayType2 dt2;

    f(dt1);
    f(dt2);
}


//-------------------------------------------------
// TEMPLATED VERSION
//-------------------------------------------------
#include <iostream>

class Display {
public:
    static const int TYPE1;
    static const int TYPE2;

    Display(const int& t) : _t(t) {}
    void process();
private:
    const int _t;
};
const int Display::TYPE1 = 0;
const int Display::TYPE2 = 1;

template <int T>
struct DisplayTraits {};

template <>
struct DisplayTraits<Display::TYPE1> {
    static inline void process() { std::cout << "Type 1\n"; }
};

template <>
struct DisplayTraits<Display::TYPE2> {
    static inline void process() { std::cout << "Type 2\n"; }
};

void Display::process() {
    //DisplayTraits<_t>::process();  ///< Don't compile, generate errors
}

void f(Display& d) { d.process(); }

int main()
{
    Display dt1(Display::TYPE1);
    Display dt2(Display::TYPE2);
    f(dt1);
    f(dt2);

    const int t = Display::TYPE2;
    DisplayTraits<t>::process();  ///< Compile without problems
}



More information about the Libstdc++ mailing list