开发者

Internal enum as a base class template parameter

pragma once

#include "stdafx.h"
#include "Token.h"

//I would like this enum to be inside class Number
enum Number_enm {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};

class Number : public Token<Number_enm>//and this template parameter to be Number::Number_enm
{
private:
    
public:
    Number(const Number_enm& num)
    try:
    Token(num)
    {   }
    catch(...)
    {
        cerr << "Error in Number::Number(const Number_enm&).";
        return;
    }
    
    Number(const char num)
    try:
    Token(static_cast<Number_enm>(num & 0xf)) //get number value from char
    {
#ifdef DEBUG_
    cout << "Converting ctor, from char to Token.\n";
#endif
    }
    catch(..开发者_JAVA百科.)
    {
        cerr << "Error in Number::Number(const char num).";
        return;
    }
    
};

#pragma once

/*Abstract class*/
template<class T>
class Token
{
    typedef T value_type;
private:
    value_type my_data_;
protected:
    /*Token()
    try: my_data_()
    {   }
    catch(...)
    {
        cerr << "Error in Token<T>::Token().";
        return;
    }*/
    Token(const value_type value)
        try:
    my_data_(value)
    {   }
    catch(...)
    {
        cerr << "Error in Token<T>::Token(const value_type&).";
        return;
    }
    /*Token(const Token& value): my_data(value)
    {   }*/
    Token& operator=(const Token& right)
    {
#ifdef DEBUG_
        cout << "Token& operator=(const Token& right).\n";
#endif
        my_data = right;
        return my_data;
    }
public:
    T get() const
    {
        return my_data_;
    }
    T set(const T& new_value)
    {
        T old = my_data_;
        my_data_ = new_value;
        return old;
    }
};

I wonder if it is possible to do this kind of construction?


No, you can't because it's not possible to forward declare an enum. Also, but not related, those contructor try blocks are a bad idea.

See also article by Herb Sutter at http://www.ddj.com/cpp/184401297 - he is slightly less condemnatory than me. Anyway, as I said, the try blocks have nothing to do with your question.


It appears to me that you can, if you fix the errors.

Edit: Missed the comment, saying that you want the enum to be inside the class: you can't do that.

1) If you want to call the constructor of the base class then that is a template:

Number(const Number_enm& num)
    try:
    Token<Number_enm>(num)

2) You can't return from a constructor-level try block. You can only exit by (re)throwing - I assume not doing anything defaults to rethrowing.

Anyway, what kind of exceptions are you expecting from such simple types?

3) In one place you are referring to my_data instead of my_data_. But then, why do you implement the copy constructor and assignment operator if they have the default behavior? (The latter should return *this.)


There is a way to put your enum in your class! ...kind of

I wanted to do this as well, and the solution I came up with relies on the fact that an enum always has an underlying type (int by default on all compilers that I am familiar with). You have to specify 'int' instead of your enum in all places that the base class expects it, but you can pass your enum into these functions! So in your case you could do something like:

#pragma once
#include "stdafx.h"
#include "Token.h"

class Number : public Token<int> // 'int' instead of 'Number_enm'
{
private:

public:
    enum Number_enm {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};

    Number(const Number_enm& num)
    try:
    Token(num) // Passed in a Number_enm!
    {   }
    catch(...)
    {
        cerr << "Error in Number::Number(const Number_enm&).";
        return;
    }

    // I don't know what your Token class does, but I'm guessing that you
    // need to static_cast to int instead of Number_enm
    Number(const char num)
    try:
    Token(static_cast<Number_enm>(num & 0xf)) //get number value from char
    {
#ifdef DEBUG_
    cout << "Converting ctor, from char to Token.\n";
#endif
    }
    catch(...)
    {
        cerr << "Error in Number::Number(const char num).";
        return;
    }

};

I can't verify if the code above compiles without the Token class, but I have compiled code that uses this technique.

Cheers

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜