How to initialize C++ reference with different constructors based on condition?What are the differences between a pointer variable and a reference variable in C++?Can I call a constructor from another constructor (do constructor chaining) in C++?How can I profile C++ code running on Linux?Difference between 'struct' and 'typedef struct' in C++?How do I pass a variable by reference?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?How C++ reference worksWhat is an undefined reference/unresolved external symbol error and how do I fix it?Restriction for invocation of constexpr constructor in a constant initializerC++ How to initialize members with hidden default constructors?
Get the encrypted payload from an unencrypted wrapper PDF document
Is Zack Morris's 'time stop' ability in "Saved By the Bell" a supernatural ability?
Debussy as term for bathroom?
Why is the stock market so unpredictable?
Is the name of an interval between two notes unique and absolute?
Very lazy puppy
Paradox regarding phase transitions in relativistic systems
What's the purpose of autocorrelation?
Can one guy with a duplicator initiate a nuclear apocalypse?
In Game Behavior vs. Out of Game Consequences
Should I inform my future product owner that there is a good chance that a team member will leave the company soon?
Weapon class firing logic in JavaScript
Do household ovens ventilate heat to the outdoors?
How to ask a man to not take up more than one seat on public transport while avoiding conflict?
Why would a fighter use the afterburner and air brakes at the same time?
Should the pagination be reset when changing the order?
Simulate a 1D Game-of-Life-ish Model
Does Mage Hand give away the caster's position?
What is the maximum viable speed for a projectile within earth's atmosphere?
Why are there two bearded faces wearing red hats on my stealth bomber icon?
Are lay articles good enough to be the main source of information for PhD research?
Lead Amalgam as a Material for a Sword
Applications of mathematics in clinical setting
Dear Fellow PSE Users,
How to initialize C++ reference with different constructors based on condition?
What are the differences between a pointer variable and a reference variable in C++?Can I call a constructor from another constructor (do constructor chaining) in C++?How can I profile C++ code running on Linux?Difference between 'struct' and 'typedef struct' in C++?How do I pass a variable by reference?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?How C++ reference worksWhat is an undefined reference/unresolved external symbol error and how do I fix it?Restriction for invocation of constexpr constructor in a constant initializerC++ How to initialize members with hidden default constructors?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
The reference variable foo below is initialized with either an instance of Foo or its derived class Bar based on condition. Strangely enough, based on the output of the say() method, foo seems to be an instance of Foo rather than an instance of Bar — why?
#include <iostream>
class Foo
public:
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
If I annotate each constructor I can see that the Bar constructor is getting invoked when evaluating the ternary expression. If I annotate each destructor I see that Bar destructor is invoked before foo is initialized — this tells me that a temporary Bar object is created by the ternary operator, but is destroyed before initialization — why?
Compiled with (Apple LLVM version 9.0.0 (clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
c++ reference
add a comment
|
The reference variable foo below is initialized with either an instance of Foo or its derived class Bar based on condition. Strangely enough, based on the output of the say() method, foo seems to be an instance of Foo rather than an instance of Bar — why?
#include <iostream>
class Foo
public:
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
If I annotate each constructor I can see that the Bar constructor is getting invoked when evaluating the ternary expression. If I annotate each destructor I see that Bar destructor is invoked before foo is initialized — this tells me that a temporary Bar object is created by the ternary operator, but is destroyed before initialization — why?
Compiled with (Apple LLVM version 9.0.0 (clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
c++ reference
add a comment
|
The reference variable foo below is initialized with either an instance of Foo or its derived class Bar based on condition. Strangely enough, based on the output of the say() method, foo seems to be an instance of Foo rather than an instance of Bar — why?
#include <iostream>
class Foo
public:
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
If I annotate each constructor I can see that the Bar constructor is getting invoked when evaluating the ternary expression. If I annotate each destructor I see that Bar destructor is invoked before foo is initialized — this tells me that a temporary Bar object is created by the ternary operator, but is destroyed before initialization — why?
Compiled with (Apple LLVM version 9.0.0 (clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
c++ reference
The reference variable foo below is initialized with either an instance of Foo or its derived class Bar based on condition. Strangely enough, based on the output of the say() method, foo seems to be an instance of Foo rather than an instance of Bar — why?
#include <iostream>
class Foo
public:
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
If I annotate each constructor I can see that the Bar constructor is getting invoked when evaluating the ternary expression. If I annotate each destructor I see that Bar destructor is invoked before foo is initialized — this tells me that a temporary Bar object is created by the ternary operator, but is destroyed before initialization — why?
Compiled with (Apple LLVM version 9.0.0 (clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
c++ reference
c++ reference
asked Mar 28 at 14:16
wcochranwcochran
5,6974 gold badges39 silver badges51 bronze badges
5,6974 gold badges39 silver badges51 bronze badges
add a comment
|
add a comment
|
1 Answer
1
active
oldest
votes
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to writenewanddeleteis really nice.
– NathanOliver
Mar 28 at 15:26
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55399830%2fhow-to-initialize-c-reference-with-different-constructors-based-on-condition%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to writenewanddeleteis really nice.
– NathanOliver
Mar 28 at 15:26
add a comment
|
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to writenewanddeleteis really nice.
– NathanOliver
Mar 28 at 15:26
add a comment
|
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
The problem with
const Foo& foo = condition ? Foo() : Bar();
is that both parts need to return the same type. Since Foo() and Bar() aren't the same type, the compiler tries to convert them. The only valid conversion it can do is to slice Bar() into its Foo part. This means no matter what you get, you'll be binding a reference to a Foo and the Bar part disappears.
To fix this you'll need to use pointers like
#include <iostream>
#include <memory>
class Foo
public:
virtual ~Foo() = default; // don't forget to add this when using polymorphism
virtual void say() const
std::cout << "Foon";
;
class Bar : public Foo
public:
virtual void say() const
std::cout << "Barn";
;
int main()
constexpr bool condition = false;
auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
foo->say(); // outputs "Bar" now
return 0;
answered Mar 28 at 14:26
NathanOliverNathanOliver
115k19 gold badges182 silver badges263 bronze badges
115k19 gold badges182 silver badges263 bronze badges
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to writenewanddeleteis really nice.
– NathanOliver
Mar 28 at 15:26
add a comment
|
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to writenewanddeleteis really nice.
– NathanOliver
Mar 28 at 15:26
1
1
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
Excellent. Bonus: using unique ptrs saves me from having to explicitly delete as well.
– wcochran
Mar 28 at 14:33
@wcochran Yeah, not having to write
new and delete is really nice.– NathanOliver
Mar 28 at 15:26
@wcochran Yeah, not having to write
new and delete is really nice.– NathanOliver
Mar 28 at 15:26
add a comment
|
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55399830%2fhow-to-initialize-c-reference-with-different-constructors-based-on-condition%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown