May I change the held type in a std::variant from within a call to std::visit2019 Community Moderator ElectionImplementing is_constexpr_copiableHow does std::visit work with std::variant?Visit and invoke a variant of std::functionVisit a variant with a monostateHow to simplify std::variant class typesis decltype required in trailing return using value of argument typeget currently held typeid of std::variant (like boost::variant type())noexcept visitation for std::variantHow to use std::visit with std::variant containing enumPredefined type list passed to a std::variant
PTIJ: Who should I vote for? (21st Knesset Edition)
how to write formula in word in latex
How can I track script which gives me "command not found" right after the login?
Does someone need to be connected to my network to sniff HTTP requests?
How to write cleanly even if my character uses expletive language?
Is it true that good novels will automatically sell themselves on Amazon (and so on) and there is no need for one to waste time promoting?
How to change two letters closest to a string and one letter immediately after a string using notepad++
How Could an Airship Be Repaired Mid-Flight
Look at your watch and tell me what time is it. vs Look at your watch and tell me what time it is
Why do passenger jet manufacturers design their planes with stall prevention systems?
Employee lack of ownership
If the DM rolls initiative once for a group of monsters, how do end-of-turn effects work?
Why Choose Less Effective Armour Types?
Should we release the security issues we found in our product as CVE or we can just update those on weekly release notes?
How to read the value of this capacitor?
How do I hide Chekhov's Gun?
Bach's Toccata and Fugue in D minor breaks the "no parallel octaves" rule?
Creature kill and resurrect effects on the stack interaction?
SOQL: Populate a Literal List in WHERE IN Clause
Interplanetary conflict, some disease destroys the ability to understand or appreciate music
Why did it take so long to abandon sail after steamships were demonstrated?
How to use deus ex machina safely?
Is this a real picture of Jordan Peterson in New Zealand with a fan wearing a shirt that says "I'm a Proud Islamaphobe"?
If I can solve Sudoku can I solve Travelling Salesman Problem(TSP)? If yes, how?
May I change the held type in a std::variant from within a call to std::visit
2019 Community Moderator ElectionImplementing is_constexpr_copiableHow does std::visit work with std::variant?Visit and invoke a variant of std::functionVisit a variant with a monostateHow to simplify std::variant class typesis decltype required in trailing return using value of argument typeget currently held typeid of std::variant (like boost::variant type())noexcept visitation for std::variantHow to use std::visit with std::variant containing enumPredefined type list passed to a std::variant
Does the following code invoke undefined behaviour?
std::variant<A,B> v = ...;
std::visit([&v](auto& e)
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
, v);
In particular, when the variant does not contain an A
,
this code re-assigns an A
while still holding a reference to the previously held object of type B
.
However, because the reference is not used anymore after the assignment,
I feel the code is fine.
However, would a standard-library be free to implement std::visit
in a way such that the above is undefined behaviour?
c++ c++17 std-variant
add a comment |
Does the following code invoke undefined behaviour?
std::variant<A,B> v = ...;
std::visit([&v](auto& e)
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
, v);
In particular, when the variant does not contain an A
,
this code re-assigns an A
while still holding a reference to the previously held object of type B
.
However, because the reference is not used anymore after the assignment,
I feel the code is fine.
However, would a standard-library be free to implement std::visit
in a way such that the above is undefined behaviour?
c++ c++17 std-variant
5
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
1
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, sincestd::visit(vis, variant)
should be equivalent tovis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain
– Justin
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago
add a comment |
Does the following code invoke undefined behaviour?
std::variant<A,B> v = ...;
std::visit([&v](auto& e)
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
, v);
In particular, when the variant does not contain an A
,
this code re-assigns an A
while still holding a reference to the previously held object of type B
.
However, because the reference is not used anymore after the assignment,
I feel the code is fine.
However, would a standard-library be free to implement std::visit
in a way such that the above is undefined behaviour?
c++ c++17 std-variant
Does the following code invoke undefined behaviour?
std::variant<A,B> v = ...;
std::visit([&v](auto& e)
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
, v);
In particular, when the variant does not contain an A
,
this code re-assigns an A
while still holding a reference to the previously held object of type B
.
However, because the reference is not used anymore after the assignment,
I feel the code is fine.
However, would a standard-library be free to implement std::visit
in a way such that the above is undefined behaviour?
c++ c++17 std-variant
c++ c++17 std-variant
edited 12 hours ago
Barry
184k21324595
184k21324595
asked 13 hours ago
burnpanckburnpanck
1,141622
1,141622
5
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
1
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, sincestd::visit(vis, variant)
should be equivalent tovis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain
– Justin
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago
add a comment |
5
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
1
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, sincestd::visit(vis, variant)
should be equivalent tovis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain
– Justin
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago
5
5
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
1
1
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, since
std::visit(vis, variant)
should be equivalent to vis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain– Justin
12 hours ago
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, since
std::visit(vis, variant)
should be equivalent to vis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain– Justin
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago
add a comment |
1 Answer
1
active
oldest
votes
The code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
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/3.0/"u003ecc by-sa 3.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');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
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%2f55187548%2fmay-i-change-the-held-type-in-a-stdvariant-from-within-a-call-to-stdvisit%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 code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
add a comment |
The code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
add a comment |
The code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
The code is fine.
There is no requirement in the specification of std::visit
that the visitor not change the alternative of any of the variants it is invoked on. The only requirement is:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
Your visitor is a valid expression for each m
and always returns void
, so it satisfies the requirements and has well-defined behavior.
answered 12 hours ago
BarryBarry
184k21324595
184k21324595
add a comment |
add a comment |
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');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
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%2f55187548%2fmay-i-change-the-held-type-in-a-stdvariant-from-within-a-call-to-stdvisit%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');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
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');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
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');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
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
5
Do you want quotes from the standard to back up the answer(s) you get?
– NathanOliver
12 hours ago
1
From looking at [variant.visit], I'm 99% sure this code is compliant and guaranteed not to have UB, since
std::visit(vis, variant)
should be equivalent tovis(get</* active member */>(variant))
, but I'm not confident enough in reading the standard to be certain– Justin
12 hours ago
@NathanOliver: I don't need actual quotes from the standard, as long as the experts here can agree on the answer:-).
– burnpanck
12 hours ago