This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Is that code valid ?


Lassi Tuuren wrote:
>
> Olivier Galibert wrote:
> > kftabdlg.cpp:549: parse error before `;'
> > Line 549 is "return(QDate::QDate());"
> > 
> > Changing that line to "return QDate();" works perfectly though.
> 
> That is valid code, since the class name is found in its own scope. 
> Hence, one should be able to repeat `QDate::' arbitrary many times.  > In
> other words, assuming the proper declarations, the following is
> perfectly valid, albeit weird code:
> 
>  return (QDate::QDate::QDate::QDate ());

Please, do not write things out of thin air in this forum.
Note that the constructor of a class has no name:
------------------------------------------------------------------------
  12.1  Constructors                                        [class.ctor]

1 Constructors  do not have names.  A special declarator syntax using an
  optional function-specifier (_dcl.fct.spec_) followed by the construc-
  tor's  class  name  followed by a parameter list is used to declare or
  define the constructor.  In such a declaration,  optional  parentheses
  around the constructor class name are ignored.  [Example:
          class C {
          public:
                  C();       // declares the constructor
          };

          C::C() { }         // defines the constructor
   --end example]

2 A  constructor  is  used  to  initialize  objects  of  its class type.
  Because constructors do not have names, they are  never  found  during
  name  lookup; however an explicit type conversion using the functional
  notation (_expr.type.conv_) will cause a constructor to be  called  to
  initialize  an  object.  [Note: for initialization of objects of class
  type see _class.init_.  ]
------------------------------------------------------------------------

The way the code works is through the _expr.type.conv_ mechanism which 
states:

------------------------------------------------------------------------
  5.2.3  Explicit type conversion (functional           [expr.type.conv]
       notation)

1 A  simple-type-specifier  (_dcl.type_)  followed  by  a  parenthesized
  expression-list  constructs  a  value  of the specified type given the
  expression list.  If the expression list is a single  expression,  the
  type  conversion  expression  is  equivalent  (in  definedness, and if
  defined   in   meaning)   to   the   corresponding   cast   expression
  (_expr.cast_).   If  the simple-type-specifier specifies a class type,
  the class type shall be complete.  If the  expression  list  specifies
  more  than  a  single value, the type shall be a class with a suitably
  declared constructor (_dcl.init_, _class.ctor_),  and  the  expression

  T(x1, x2, ...)  is equivalent in effect to the declaration T t(x1, x2,
  ...); for some invented temporary variable t, with  the  result  being
  the value of t as an rvalue.

2 The expression T(), where T is a simple-type-specifier (_dcl.type.sim-
  ple_) for a non-array complete object type or the (possibly  cv-quali-
  fied)  void type, creates an rvalue of the specified type, whose value
  is determined by default-initialization (_dcl.init_).  [Note: if T  is
  a  non-class  type that is cv-qualified, the cv-qualifiers are ignored
  when determining the type of the resulting rvalue (_basic.lval_).  ]
------------------------------------------------------------------------

So, when you write:

	return Class(1, 2, 3);

You are creating a temporary with the result being an rvalue. However,
you can not use the syntax 'Class::Class(1, 2, 3)' since the last
'Class'
is _not_ a name. The only valid identifers after :: are:

          unqualified-id:
                  identifier
                  operator-function-id
                  conversion-function-id
                  ~ class-name
                  template-id

As you can see, the syntax '~ class-name' is allowed. 'class-name' is
not.
The short version of the story is:

	1. You can not "call" a constructor.
	2. You can however create a temporary object (and by this call
           the constructor) by the construct
		Class(param1, param2, ...);
	3. You can call the destructor, for instance by:
		this->~Class();

Having said this, I haven't figured out if you may use the name-space
qualifier in constructing a temporary object:

	NameSpace::Class(1, 2, 3);

Any takers?

PKE.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]