if constexpr branch does not get discarded inside lambda that is inside a template functionPossible to instantiate templates using a for loop in a C++14 constexpr function?Calling `this` member function from generic lambda - clang vs gccSFINAE constexpr with std::getShould decltype(foo(1)) instantiate the constexpr function template foo?Why can't lambda, when cast to function pointer, be used in constexpr context?Can constexpr-if-else bodies return different types in constexpr auto function?False-branch of if constexpr not discarded in templated lambdaNested constexpr-if statement in discarded branch is still evaluated?Using a constexpr static member of a reference as template argumentConstexpr static member function usage
Is lying to get "gardening leave" fraud?
Entropy as a function of temperature: is temperature well defined?
Declining welcome lunch invitation at new job due to Ramadan
How could a planet have most of its water in the atmosphere?
Map one pandas column using two dictionaries
Why do money exchangers give different rates to different bills
Binary Numbers Magic Trick
The barbers paradox first order logic formalization
Is this homebrew race based on the Draco Volans lizard species balanced?
Feels like I am getting dragged into office politics
Any examples of headwear for races with animal ears?
When do aircrafts become solarcrafts?
Who died in the Game of Thrones episode, "The Long Night"?
Why is Arya visibly scared in the library in S8E3?
If I supply 24v to a 50v rated 22000uf electrolytic capacitor, does that mean it will store 44000uf at 24v?
Can fracking help reduce CO2?
How to get SEEK accessing converted ID via view
Hang 20lb projector screen on Hardieplank
When and why did journal article titles become descriptive, rather than creatively allusive?
Melee attacking upwards (enemy on 10ft ceiling)
If 1. e4 c6 is considered as a sound defense for black, why is 1. c3 so rare?
Accidentally deleted the "/usr/share" folder
How can I close a gap between my fence and my neighbor's that's on his side of the property line?
Does hiding behind 5-ft-wide cover give full cover?
if constexpr branch does not get discarded inside lambda that is inside a template function
Possible to instantiate templates using a for loop in a C++14 constexpr function?Calling `this` member function from generic lambda - clang vs gccSFINAE constexpr with std::getShould decltype(foo(1)) instantiate the constexpr function template foo?Why can't lambda, when cast to function pointer, be used in constexpr context?Can constexpr-if-else bodies return different types in constexpr auto function?False-branch of if constexpr not discarded in templated lambdaNested constexpr-if statement in discarded branch is still evaluated?Using a constexpr static member of a reference as template argumentConstexpr static member function usage
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
The following code:
#include <type_traits>
struct X
static constexpr void x()
;
template <class T1, class T2>
constexpr bool makeFalse() return false;
template <class T>
void foo()
T tmp;
auto f = [](auto type)
if constexpr (makeFalse<T, decltype(type)>())
T::x(); // <- clang does not discard
else
// noop
;
int main()
foo<int>();
does not compile with Clang, but compiles with GCC. I can't see anything wrong with this code but I'm not sure. Is Clang right not compiling it?
c++ c++17 if-constexpr
add a comment |
The following code:
#include <type_traits>
struct X
static constexpr void x()
;
template <class T1, class T2>
constexpr bool makeFalse() return false;
template <class T>
void foo()
T tmp;
auto f = [](auto type)
if constexpr (makeFalse<T, decltype(type)>())
T::x(); // <- clang does not discard
else
// noop
;
int main()
foo<int>();
does not compile with Clang, but compiles with GCC. I can't see anything wrong with this code but I'm not sure. Is Clang right not compiling it?
c++ c++17 if-constexpr
worth mentioning thatTis not dependant on the lambda template parameter. Don't know however howif constexprshould handle that.
– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
1
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago
add a comment |
The following code:
#include <type_traits>
struct X
static constexpr void x()
;
template <class T1, class T2>
constexpr bool makeFalse() return false;
template <class T>
void foo()
T tmp;
auto f = [](auto type)
if constexpr (makeFalse<T, decltype(type)>())
T::x(); // <- clang does not discard
else
// noop
;
int main()
foo<int>();
does not compile with Clang, but compiles with GCC. I can't see anything wrong with this code but I'm not sure. Is Clang right not compiling it?
c++ c++17 if-constexpr
The following code:
#include <type_traits>
struct X
static constexpr void x()
;
template <class T1, class T2>
constexpr bool makeFalse() return false;
template <class T>
void foo()
T tmp;
auto f = [](auto type)
if constexpr (makeFalse<T, decltype(type)>())
T::x(); // <- clang does not discard
else
// noop
;
int main()
foo<int>();
does not compile with Clang, but compiles with GCC. I can't see anything wrong with this code but I'm not sure. Is Clang right not compiling it?
c++ c++17 if-constexpr
c++ c++17 if-constexpr
edited 4 hours ago
Nicol Bolas
293k34484661
293k34484661
asked 4 hours ago
nicolainicolai
326211
326211
worth mentioning thatTis not dependant on the lambda template parameter. Don't know however howif constexprshould handle that.
– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
1
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago
add a comment |
worth mentioning thatTis not dependant on the lambda template parameter. Don't know however howif constexprshould handle that.
– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
1
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago
worth mentioning that
T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.– bolov
4 hours ago
worth mentioning that
T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
1
1
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago
add a comment |
1 Answer
1
active
oldest
votes
[stmt.if]/2:
During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Since makeFalse<T, decltype(type)>() is value-dependent after the instantiation of foo<int>, it appears that T::x() should be instantiated per the standard, and since T::x is ill-formed when T is int, Clang is right not compiling it.
Wouldn't this reasoning imply that a hypotheticalif constexpr (makeFalse<decltype(type)>) type.x();would not be discarded either?
– Barry
2 hours ago
@Barry Yes. Buttype.x()is a dependent and possibly valid expression after the instantiation.
– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even ifmakeFalse<decltype(type)>isfalse? Assume it's actually an interesting check... more likeif constexpr (can_x<decltype(type)>) type.x();
– Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation offoo(2) the instantiation off's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.
– cpplearner
2 hours ago
|
show 1 more 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');
);
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%2f55909018%2fif-constexpr-branch-does-not-get-discarded-inside-lambda-that-is-inside-a-templa%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
[stmt.if]/2:
During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Since makeFalse<T, decltype(type)>() is value-dependent after the instantiation of foo<int>, it appears that T::x() should be instantiated per the standard, and since T::x is ill-formed when T is int, Clang is right not compiling it.
Wouldn't this reasoning imply that a hypotheticalif constexpr (makeFalse<decltype(type)>) type.x();would not be discarded either?
– Barry
2 hours ago
@Barry Yes. Buttype.x()is a dependent and possibly valid expression after the instantiation.
– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even ifmakeFalse<decltype(type)>isfalse? Assume it's actually an interesting check... more likeif constexpr (can_x<decltype(type)>) type.x();
– Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation offoo(2) the instantiation off's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.
– cpplearner
2 hours ago
|
show 1 more comment
[stmt.if]/2:
During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Since makeFalse<T, decltype(type)>() is value-dependent after the instantiation of foo<int>, it appears that T::x() should be instantiated per the standard, and since T::x is ill-formed when T is int, Clang is right not compiling it.
Wouldn't this reasoning imply that a hypotheticalif constexpr (makeFalse<decltype(type)>) type.x();would not be discarded either?
– Barry
2 hours ago
@Barry Yes. Buttype.x()is a dependent and possibly valid expression after the instantiation.
– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even ifmakeFalse<decltype(type)>isfalse? Assume it's actually an interesting check... more likeif constexpr (can_x<decltype(type)>) type.x();
– Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation offoo(2) the instantiation off's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.
– cpplearner
2 hours ago
|
show 1 more comment
[stmt.if]/2:
During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Since makeFalse<T, decltype(type)>() is value-dependent after the instantiation of foo<int>, it appears that T::x() should be instantiated per the standard, and since T::x is ill-formed when T is int, Clang is right not compiling it.
[stmt.if]/2:
During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Since makeFalse<T, decltype(type)>() is value-dependent after the instantiation of foo<int>, it appears that T::x() should be instantiated per the standard, and since T::x is ill-formed when T is int, Clang is right not compiling it.
answered 4 hours ago
cpplearnercpplearner
6,22122543
6,22122543
Wouldn't this reasoning imply that a hypotheticalif constexpr (makeFalse<decltype(type)>) type.x();would not be discarded either?
– Barry
2 hours ago
@Barry Yes. Buttype.x()is a dependent and possibly valid expression after the instantiation.
– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even ifmakeFalse<decltype(type)>isfalse? Assume it's actually an interesting check... more likeif constexpr (can_x<decltype(type)>) type.x();
– Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation offoo(2) the instantiation off's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.
– cpplearner
2 hours ago
|
show 1 more comment
Wouldn't this reasoning imply that a hypotheticalif constexpr (makeFalse<decltype(type)>) type.x();would not be discarded either?
– Barry
2 hours ago
@Barry Yes. Buttype.x()is a dependent and possibly valid expression after the instantiation.
– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even ifmakeFalse<decltype(type)>isfalse? Assume it's actually an interesting check... more likeif constexpr (can_x<decltype(type)>) type.x();
– Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation offoo(2) the instantiation off's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.
– cpplearner
2 hours ago
Wouldn't this reasoning imply that a hypothetical
if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?– Barry
2 hours ago
Wouldn't this reasoning imply that a hypothetical
if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?– Barry
2 hours ago
@Barry Yes. But
type.x() is a dependent and possibly valid expression after the instantiation.– cpplearner
2 hours ago
@Barry Yes. But
type.x() is a dependent and possibly valid expression after the instantiation.– cpplearner
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even if
makeFalse<decltype(type)> is false? Assume it's actually an interesting check... more like if constexpr (can_x<decltype(type)>) type.x(); – Barry
2 hours ago
I think "possibly valid" is muddling things, I don't think that's relevant necessarily. Are you saying it won't be discarded even if
makeFalse<decltype(type)> is false? Assume it's actually an interesting check... more like if constexpr (can_x<decltype(type)>) type.x(); – Barry
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
I am not convinced. Why then are my example and Amadeus compiling?
– bolov
2 hours ago
3
3
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation of
foo (2) the instantiation of f's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.– cpplearner
2 hours ago
@Barry Let me try to clarify. There are two instantiations that can be involved: (1) the instantiation of
foo (2) the instantiation of f's function call operator template (which does not happen in OP's example). (1) does not discard either branch, because the condition is still value-dependent after it. If either branch is ill-formed after (1), an error will occur (but [temp.res]/8 may kick in when an expression in a branch is dependent). (2) does discard one branch because the condition is no longer dependent.– cpplearner
2 hours ago
|
show 1 more 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');
);
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%2f55909018%2fif-constexpr-branch-does-not-get-discarded-inside-lambda-that-is-inside-a-templa%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
worth mentioning that
Tis not dependant on the lambda template parameter. Don't know however howif constexprshould handle that.– bolov
4 hours ago
(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC
– bolov
4 hours ago
1
@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6
– Amadeus
4 hours ago