views:

582

answers:

5

When I write code like this in 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() {}
};

I then initialize my structure like this:

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

The compiler gives the following errors:

'Patterns': the symbol to the left of a '::' must be a type 'ptSelect' : is not a member of 'QueryValidate'

What am I doing wrong? Is this a problem with Visual Studio or with my code? I know that static members except for const ones must be defined outside the class they were declared in.

+9  A: 

You're trying to create a non-static member (ptCreate) of a static member (pts). This won't work like this.

You got two options, either use a struct initializer list for the Patterns class.

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

Or, much safer (and better in my opinion), provide a constructor in Patterns and call that one.

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

On a side not, your code wouldn't work in any C++ compiler, it's not a conflict with Visual Studio things.

Pieter
+1  A: 

This isn't valid C++. In the cpp file you're declaring parts of the static structure "QueryValidate::pts", but that's not allowed: you've got to declare the whole structure, like so:

Patterns QueryValidate::pts;

if you want members to be initialized, you either initialize them in another method, or add a constructor to Patterns that takes whatever initialization arguments you want.

DavidK
There's an important difference between 'declaring' and 'defining'. The guy is defining part of the static structure. Other than that, you're right, of course.
xtofl
+3  A: 

You can only initialize the structure as a whole, as in:

Patterns QueryValidate::pts = { "something", "something", ... };
peterchen
A: 

I'm not real sure what you are trying to do here. It looks kind of like you are trying to declare and initialize each field in pts separately, rather than declare pts once as a single object. I'm really surprised VS lets you do that.

What worked for me in gcc was the following:

Patterns QueryValidate::pts;

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

thanks for comments, it was really an improvement in my knowledge of C++

chester89