3

Recently, I saw a unfamiliar statement for C++ template, something like:

    x3::rule<class expression> const expression("expression");
    x3::rule<class term> const term("term");
    x3::rule<class factor> const factor("factor");

It's an exmaple source code for Boost.Spirit.X3(https://github.com/djowel/spirit_x3/blob/master/example/x3/calc1.cpp#L41)

It seems that these lines declare expression, term, and factor variable of template class x3::rule. What's curious thing is <class expression> part for example. I've never seen such statemet ever.

When declare a variable of template class, one specify 'a type' as template argument, so I can guess 'class expression' means some type. However, expression is a name of variable and the combination of a keyword 'class', that is, 'class expression' seems awkward. Further more, the variable 'expression' is not yet declared when instantiate x3::rule. Is it something like forward declaration using variable name?

Please let me know how these declarations work and the term for such statements if any.

slyx
  • 2,063
  • 1
  • 19
  • 28
  • 1
    It's just using a "temporary type" as the argument. See http://stackoverflow.com/questions/14232293/how-to-define-different-types-for-the-same-class-in-c (and holy cow, how did I find that?) – chris Jul 16 '14 at 01:03
  • @chris It wasn't a difficult or complicated thing. Thank you! – slyx Jul 19 '14 at 15:48

1 Answers1

2

Consider the statement :

x3::rule<class expression> const expression("expression");

class expression declares a new type (expression) AND use it as a template argument of the rule<> template. It is often called a temporary type, since it will be used nowhere else (the type is incomplete).

  • In your example, expression, term and factor all have different types.
  • In C++, a variable can have the same name as a type, which is what the author does here.

Here is a minimal demonstration :

template<class T>
class rule
{
    public:
       std::string rules;  
};

int main(int argc, char** argv) {

  rule<class myexpression> myexpression;
  rule<class myexpression2> myexpression2;

  myexpression.rules = "hello";
  myexpression2.rules = "hello2";
  return 0;
}
quantdev
  • 23,517
  • 5
  • 55
  • 88
  • 2
    Does it serve a purpose to name the temporary type and the variable the same ? Because if not, it is just confusing the reader, why not write `x3::rule const expression("expression")` instead ? – v.oddou Jul 16 '14 at 05:42
  • So, it's just another form of 'forward declaration' and it won't be a problem as far as noone access any member of that argument class. Thank you! – slyx Jul 19 '14 at 15:47