Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conversion operator in direct-initialization

The C++14 standard (N4296) says in 8.5/17.6.1

If the initialization is direct-initialization [...], constructors are considered. The applicable constructors are enumerated, and the best one is chosen through overload resolution. [...] If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.

Therefore in direct-initialization, only constructors are considered - conversion functions are ignored. In the following code there is no applicable constructor of A, only a conversion function from B. However, the code compiles, why?

struct A{};
struct B{
    operator A(){ return A{}; }
};

int main() {
    B b;
    A a(b);  // direct-initialization
}
like image 758
Jan Tušil Avatar asked Jun 20 '19 16:06

Jan Tušil


People also ask

What is a conversion operator?

A conversion operator, in C#, is an operator that is used to declare a conversion on a user-defined type so that an object of that type can be converted to or from another user-defined type or basic type. The two different types of user-defined conversions include implicit and explicit conversions.

Which operator is used for initializing?

The INI operator is used for initializing retain variables of a function block instance used in a POU. Assign the operator to a Boolean variable. If the second parameter of the operator yields TRUE , then CODESYS initializes all retain variables that are defined in the FB function block.

What is a conversion operator in CPP?

Conversion Operators in C++ C++ supports object oriented design. So we can create classes of some real world objects as concrete types. Sometimes we need to convert some concrete type objects to some other type objects or some primitive datatypes. To make this conversion we can use conversion operator.

What do you mean by direct initialization?

Direct initialization is performed in the following situations: 1) initialization with a nonempty parenthesized list of expressions. 2) during list-initialization sequence, if no initializer-list constructors are provided and a matching constructor is accessible, and all necessary implicit conversions are non-narrowing ...


1 Answers

You are correct that only the constructors of A are considered when doing A a(b);. [over.match.ctor]/1 states

When objects of class type are direct-initialized, copy-initialized from an expression of the same or a derived class type ([dcl.init]), or default-initialized, overload resolution selects the constructor. For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization (including default initialization in the context of copy-initialization), the candidate functions are all the converting constructors ([class.conv.ctor]) of that class. The argument list is the expression-list or assignment-expression of the initializer.

emphasis mine

This means that A(), A(const A&) and A(A&&) are the candidate list. Then we have [over.match.viable]/4

[...]Third, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F.[..]

which allows an implicit conversion of b to an A so that A(A&&) can be called.

like image 173
NathanOliver Avatar answered Sep 25 '22 16:09

NathanOliver