Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a constructor, that is not a special member function, still a member function?

From the C++ standard working draft:

Default constructors ([class.default.ctor]), copy constructors, move constructors ([class.copy.ctor]), copy assignment operators, move assignment operators ([class.copy.assign]), and prospective destructors ([class.dtor]) are special member functions.

(https://eel.is/c++draft/special)

Given the following code:

struct S {
    S(int, float, double);
};

In my understanding, the constructor of S is not a special member function, since it is neither a default constructor, copy constructor, nor move constructor.

I would like to know whether the standard still considers such as constructor a member function (or something "unique").

I read the parts of the C++ working draft about member functions, special member functions, and constructors, but didn't find anything reasonable answering this question. I also looked on StackOverflow, but most answers state that all constructors are considered special member functions, which seems to contradict the standard.

like image 278
coder2k Avatar asked Nov 02 '25 19:11

coder2k


1 Answers

tldr;

A constructor is declared using a function-declarator and so it is a function and hence a member function.


Language-lawyered Explanation

class.mem states:

The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere. A direct member of a class X is a member of X that was first declared within the member-specification of X, including anonymous union members ([class.union.anon]) and direct members thereof. Members of a class are data members, member functions ([class.mfct]), nested types, enumerators, and member templates ([temp.mem]) and specializations thereof.

Now we move onto class.mem#general-3 to see what is a member function:

A data member is a non-function member introduced by a member-declarator. A member function is a member that is a function. Nested types are classes ([class.name], [class.nest]) and enumerations ([dcl.enum]) declared in the class and arbitrary types declared as members by use of a typedef declaration ([dcl.typedef]) or alias-declaration. The enumerators of an unscoped enumeration defined in the class are members of the class.

Now we need to show that a ctor is a function so we move onto class.ctor.general#1:

A declarator declares a constructor if it is a function declarator ([dcl.fct]) of the form

ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:

  • in a friend declaration ([class.friend]), the id-expression is a qualified-id that names a constructor ([class.qual]);
  • otherwise, in a member-declaration that belongs to the member-specification of a class or class template, the id-expression is the injected-class-name ([class.pre]) of the immediately-enclosing entity;

The important thing to note is that a ctor is declared using a declarator which is a function declarator. Now to see that the ctor's function declarator declares a function we move onto dcl.spec.auto.general:

A placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid. If the function declarator includes a trailing-return-type ([dcl.fct]), that trailing-return-type specifies the declared return type of the function. Otherwise, the function declarator shall declare a function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded return statements, if any, in the body of the function ([stmt.if]).

Now since the ctor's function declarator form doesn't include a trailing return type, the ctor's function declarator declares a function as per the above reference.

Hence proved, the ctor S::S(int, float, double) is a function and so a member function.

Additional support

There is additional support for the statement that a constructor is a function in dcl.constexpr:

A function is constexpr-suitable if:

  • if the function is a constructor or destructor, its class does not have any virtual base classes.

This also indicates that a constructor is a function.


Layman Explanation

Is a constructor, that is not a special member function, still a member function?

Yes, because the constructor S::S(int, float, double) is declared inside the member-specification of the class S so the declaration is by definition a member function declaration.

Basically, declarations inside the member-specification of the class are member declarations. If the declaration is of a

  • variable, it is called member variable and
  • if the declaration is of a function then it is called a member function.

So yes, S::S(int, float, double) is a member function.

like image 109
Anoop Rana Avatar answered Nov 04 '25 11:11

Anoop Rana