0
class MyClass
{
public:
         ...
private:
    enum class BDTNodeType : unsigned char
    {
        NT_TERMINAL_ZERO,
        NT_TERMINAL_ONE,
        NT_TERMINAL_X,
        NT_NOT_TERMINAL
    };

    class BDTNode
    {
    public:
        explicit BDTNode(BDTNodeType node_type = BDTNodeType::NT_NOT_TERMINAL);
        BDTNode(const BDTNode &node);
        ~BDTNode();

        BDTNodeType type;
        BDTNode *thenPtr;   //1
        BDTNode *elsePtr;   //0
    };

    BDTNode *root_node;

    //Constant nodes
    static const BDTNode fv_nodes[3] = {
        BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
        BDTNode(BDTNodeType::NT_TERMINAL_ONE),
        BDTNode(BDTNodeType::NT_TERMINAL_X)
    };
};

I want to initialize static const BDTNode fv_nodes array directly inside the class declaration, since C++11 allows to do this. But I get "C2864: 'MyClass::fv_nodes' : a static data member with an in-class initializer must have non-volatile const integral". And I can't initialize it outside class, because in that case "BDTNode" class would be inaccessible. So how should I do this?

2 Answers 2

6

C++11 allows to do this

No, C++11 doesn't allow this. You may be thinking of non-static member initialisers, which are allowed as an alternative to initialisation in a constructor.

For static members, the rules haven't changed much. The in-class declaration is not a definition and, unless it's a non-volatile const integral or enumeration type and not odr-used, it needs a single definition outside the class. If you provide an initialiser, that goes on the definition.

And I can't initialize it outside class, because in that case "BDTNode" class would be inaccessible.

No, the initialiser is in the scope of the class, so private names are accessible. The following works for me:

// in class
static const BDTNode fv_nodes[3];

// in a source file
const MyClass::BDTNode MyClass::fv_nodes[3] = {
    BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
    BDTNode(BDTNodeType::NT_TERMINAL_ONE),
    BDTNode(BDTNodeType::NT_TERMINAL_X)
};
1

but you can do this with a static function if you wish:

This did change in c++11 in that it because thread-safe without the explicit use of a mutex.

#include <array>

class MyClass
{
public:
    //    ...
private:
    enum class BDTNodeType : unsigned char
    {
        NT_TERMINAL_ZERO,
        NT_TERMINAL_ONE,
        NT_TERMINAL_X,
        NT_NOT_TERMINAL
    };

    class BDTNode
    {
    public:
        explicit BDTNode(BDTNodeType node_type = BDTNodeType::NT_NOT_TERMINAL);
        BDTNode(const BDTNode &node);
        ~BDTNode();

        BDTNodeType type;
        BDTNode *thenPtr;   //1
        BDTNode *elsePtr;   //0
    };

    BDTNode *root_node;

    static const std::array<BDTNode, 3>& fv_nodes() {
        static const std::array<BDTNode, 3> _fv_nodes {
            BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
            BDTNode(BDTNodeType::NT_TERMINAL_ONE),
            BDTNode(BDTNodeType::NT_TERMINAL_X)
        };
        return _fv_nodes;
    }

    static const BDTNode& fv_node(size_t i) {
        assert(i < 3);
        return fv_nodes()[i];
    }
};

Not the answer you're looking for? Browse other questions tagged or ask your own question.