2014-12-19 3 views
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) 
    }; 
}; 

Я хочу инициализировать массив static const BDTNode fv_nodes непосредственно внутри объявления класса, поскольку C++ 11 позволяет это сделать. Но я получаю «C2864:« MyClass :: fv_nodes »: статический член данных с инициализатором в классе должен иметь нестабильный const-интеграл». И я не могу инициализировать его вне класса, потому что в этом случае класс «BDTNode» был бы недоступен. Итак, как мне это сделать?Инициализация частного элемента static const array

ответ

6

C++ 11 позволяет сделать это

Нет, C++ 11 не позволяет. Вы можете думать о нестатических инициаторах членов, которые разрешены в качестве альтернативы инициализации в конструкторе.

Для статических членов правила не сильно изменились. Объявление в классе не является определением, и, если оно не является энергонезависимым интегральным или перечисляемым типом и не используется odr, ему требуется одно определение вне класса. Если вы предоставите инициализатор, это определение.

И я не могу инициализировать его вне класса, потому что в этом случае класс «BDTNode» был бы недоступен.

Нет, инициализатор находится в сфере действия класса, поэтому доступны частные имена. Следующий 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

, но вы можете сделать это с помощью статической функции, если вы хотите:

Это сделал изменения в C++ 11 в том, что это потому, что поточно-без явного использования мьютекс.

#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]; 
    } 
}; 
Смежные вопросы