Почему я не могу использовать статические члены, например статические структуры, в своих классах в VS2008? - PullRequest
3 голосов
/ 07 ноября 2008

Когда я пишу такой код в VS 2008:

.h
struct Patterns {
        string ptCreate;
        string ptDelete;
        string ptDrop;
        string ptUpdate;
        string ptInsert;
        string ptSelect;
    };     

class QueryValidate {
    string query;
    string pattern;
    static Patterns pts;
public:
    friend class Query;
    QueryValidate(const string& qr, const string& ptn):
      query(qr), pattern(ptn) {}
    bool validate() {
        boost::regex rg(pattern);
        return boost::regex_match(query, rg);
    }
    virtual ~QueryValidate() {}
};

Затем я инициализирую свою структуру следующим образом:

.cpp
string QueryValidate::pts::ptCreate = "something";
string QueryValidate::pts::ptDelete = "something";
//...

Компилятор выдает следующие ошибки:

'Шаблоны': символ слева от '::' должен иметь тип 'ptSelect' : не является членом QueryValidate

Что я делаю не так? Это проблема с Visual Studio или с моим кодом? Я знаю, что статические члены, кроме константных, должны быть определены вне класса, в котором они были объявлены.

Ответы [ 4 ]

10 голосов
/ 07 ноября 2008

Вы пытаетесь создать нестатический член (ptCreate) из статического члена (pts). Это не будет работать так.

У вас есть две опции, либо используйте список инициализатора структуры для класса Patterns.

Patterns QueryValidate::pts = {"CREATE", "DELETE"}; // etc. for every string

Или, что гораздо безопаснее (и, на мой взгляд, лучше), предоставьте конструктор в Patterns и назовите его.

struct Patterns {
   Patterns() { /*...*/ }
   /* ... */
}

С другой стороны, ваш код не будет работать в любом компиляторе C ++, это не противоречит вещам Visual Studio.

3 голосов
/ 07 ноября 2008

Вы можете только инициализировать структуру в целом, как в:

Patterns QueryValidate::pts = { "something", "something", ... };
1 голос
/ 07 ноября 2008

Это не действительно C ++. В файле cpp вы объявляете части статической структуры "QueryValidate :: pts", но это недопустимо: вам нужно объявить всю структуру, например:

Patterns QueryValidate :: pts;

если вы хотите, чтобы члены были инициализированы, вы либо инициализируете их в другом методе, либо добавляете конструктор в Patterns, который принимает любые аргументы инициализации, которые вы хотите.

0 голосов
/ 07 ноября 2008

Я не совсем уверен, что вы пытаетесь сделать здесь. Похоже, вы пытаетесь объявить и инициализировать каждое поле в pts отдельно, а не объявлять pts один раз как один объект. Я очень удивлен, что VS позволяет вам сделать это.

В gcc у меня сработало следующее:

Patterns QueryValidate::pts;

void foo () {
    QueryValidate::pts.ptCreate = "something";
    QueryValidate::pts.ptDelete = "something";
}
...