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.
tldr;
A constructor is declared using a function-declarator and so it is a function and hence a member function.
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.
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.
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
So yes, S::S(int, float, double)
is a member function.