usfmohy
usfmohy

Reputation: 43

Class reference to an object instantiated by a literal

What is happening here?

struct A {
    A (int){std::cout<<'A';}
};
const A& a = 3;

My assumption is since the literal 3 is an rvalue, temporary materialization conversion is applied. A temporary object is created by calling the constructor thus printing A and the reference is bound to the resulting object.

Upvotes: 1

Views: 72

Answers (2)

Michael Kenzel
Michael Kenzel

Reputation: 15951

You are correct. a is an lvalue reference [dcl.ref]/2 to a const-qualified class type, the initializer expression 3 is a prvalue [expr.prim.literal]/1 of non-class type int [lex.icon]/2 that is neither reference-related nor reference-compatible to const A [dcl.init.ref]/4. Therefore, [dcl.init.ref]/5.4.1 would seem to apply. There is a converting constructor [class.conv.ctor]/1, which will be used to convert 3 to a prvalue of type const A, which is then used to initialize the reference. This time around, the intializer expression now is a prvalue of type const A, which is reference related to const A. Thus, [dcl.init.ref]/5.3 should apply, which will perform temporary materialization [conv.rval]. The lifetime of the temporary object created in the process will be extended [class.temporary]/6 since it is being bound to the reference a which lives in global namespace scope…

Upvotes: 2

the boy
the boy

Reputation: 243

implicit conversion was occured. it converted from 3 to an object of A, then reference a point to this object.

better practice is add keyword explicit in constructor which take only one parameter like this. then no implicit conversion happen. then below code will throw error.

refer: https://www.geeksforgeeks.org/g-fact-35/

https://www.learncpp.com/cpp-tutorial/9-13-converting-constructors-explicit-and-delete/

struct A {
   explicit A (int){std::cout<<'A';}
};
const A& a = 3;

Upvotes: 0

Related Questions