An 'if constexpr branch' does not get discarded inside lambda that is inside a template functionC++0x error with constexpr and returning template functionPossible to instantiate templates using a for loop in a C++14 constexpr function?Calling `this` member function from generic lambda - clang vs gccInitializing a static constexpr data member of the base class by using a static constexpr data member of the derived classSFINAE constexpr with std::getStatic templated constexpr nested class memberShould decltype(foo(1)) instantiate the constexpr function template foo?Why can't lambda, when cast to function pointer, be used in constexpr context?False-branch of if constexpr not discarded in templated lambdaNested constexpr-if statement in discarded branch is still evaluated?

How do inspiraling black holes get closer?

In Stroustrup's example, what does this colon mean in `return 1 : 2`? It's not a label or ternary operator

How do LIGO and VIRGO know that a gravitational wave has its origin in a neutron star or a black hole?

Appropriate certificate to ask for a fibre installation (ANSI/TIA-568.3-D?)

How can I get people to remember my character's gender?

Building a list of products from the elements in another list

Where in Bitcoin Core does it do X?

What is the solution to this metapuzzle from a university puzzling column?

Why does this derived table improve performance?

Is there an official reason for not adding a post-credits scene?

Emotional immaturity of comic-book version of superhero Shazam

Why wasn't the Night King naked in S08E03?

Understanding trademark infringements in a world where many dictionary words are trademarks?

Has the Hulk always been able to talk?

Will 700 more planes a day fly because of the Heathrow expansion?

How can I support myself financially as a 17 year old with a loan?

Should I mention being denied entry to UK due to a confusion in my Visa and Ticket bookings?

Are Finitely generated modules over a ring also finitely generated over a subring containing the identity?

Word meaning as function of the composition of its phonemes

Why did the Apollo 13 crew extend the LM landing gear?

What exactly are the `size issues' preventing formation of presheaves being a left adjoint to some forgetful functor?

Adjacent DEM color matching in QGIS

Upside-Down Pyramid Addition...REVERSED!

Where is the documentation for this ex command?



An 'if constexpr branch' does not get discarded inside lambda that is inside a template function


C++0x error with constexpr and returning template functionPossible to instantiate templates using a for loop in a C++14 constexpr function?Calling `this` member function from generic lambda - clang vs gccInitializing a static constexpr data member of the base class by using a static constexpr data member of the derived classSFINAE constexpr with std::getStatic templated constexpr nested class memberShould decltype(foo(1)) instantiate the constexpr function template foo?Why can't lambda, when cast to function pointer, be used in constexpr context?False-branch of if constexpr not discarded in templated lambdaNested constexpr-if statement in discarded branch is still evaluated?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








24















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?










share|improve this question
























  • worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

    – bolov
    Apr 29 at 19:00











  • (somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

    – bolov
    Apr 29 at 19:03







  • 1





    @bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

    – Amadeus
    Apr 29 at 19:08

















24















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?










share|improve this question
























  • worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

    – bolov
    Apr 29 at 19:00











  • (somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

    – bolov
    Apr 29 at 19:03







  • 1





    @bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

    – Amadeus
    Apr 29 at 19:08













24












24








24


6






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 29 at 23:33









Peter Mortensen

14k1987114




14k1987114










asked Apr 29 at 18:34









nicolainicolai

366211




366211












  • worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

    – bolov
    Apr 29 at 19:00











  • (somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

    – bolov
    Apr 29 at 19:03







  • 1





    @bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

    – Amadeus
    Apr 29 at 19:08

















  • worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

    – bolov
    Apr 29 at 19:00











  • (somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

    – bolov
    Apr 29 at 19:03







  • 1





    @bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

    – Amadeus
    Apr 29 at 19:08
















worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

– bolov
Apr 29 at 19:00





worth mentioning that T is not dependant on the lambda template parameter. Don't know however how if constexpr should handle that.

– bolov
Apr 29 at 19:00













(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

– bolov
Apr 29 at 19:03






(somewhat) equivalent example without lambda compiles fine , so I suspect it's a clang bug godbolt.org/z/Xok1wC

– bolov
Apr 29 at 19:03





1




1





@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

– Amadeus
Apr 29 at 19:08





@bolov if you remove the generic lambda, it compiles too: godbolt.org/z/xoTBT6

– Amadeus
Apr 29 at 19:08












1 Answer
1






active

oldest

votes


















17














[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.






share|improve this answer























  • Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

    – Barry
    Apr 29 at 20:36











  • @Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

    – cpplearner
    Apr 29 at 20:52












  • 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
    Apr 29 at 20:56






  • 5





    @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
    Apr 29 at 21:09






  • 6





    This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

    – T.C.
    Apr 30 at 2:17











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
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55909018%2fan-if-constexpr-branch-does-not-get-discarded-inside-lambda-that-is-inside-a-t%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









17














[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.






share|improve this answer























  • Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

    – Barry
    Apr 29 at 20:36











  • @Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

    – cpplearner
    Apr 29 at 20:52












  • 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
    Apr 29 at 20:56






  • 5





    @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
    Apr 29 at 21:09






  • 6





    This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

    – T.C.
    Apr 30 at 2:17















17














[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.






share|improve this answer























  • Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

    – Barry
    Apr 29 at 20:36











  • @Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

    – cpplearner
    Apr 29 at 20:52












  • 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
    Apr 29 at 20:56






  • 5





    @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
    Apr 29 at 21:09






  • 6





    This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

    – T.C.
    Apr 30 at 2:17













17












17








17







[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.






share|improve this answer













[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.







share|improve this answer












share|improve this answer



share|improve this answer










answered Apr 29 at 19:12









cpplearnercpplearner

6,32122645




6,32122645












  • Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

    – Barry
    Apr 29 at 20:36











  • @Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

    – cpplearner
    Apr 29 at 20:52












  • 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
    Apr 29 at 20:56






  • 5





    @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
    Apr 29 at 21:09






  • 6





    This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

    – T.C.
    Apr 30 at 2:17

















  • Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

    – Barry
    Apr 29 at 20:36











  • @Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

    – cpplearner
    Apr 29 at 20:52












  • 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
    Apr 29 at 20:56






  • 5





    @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
    Apr 29 at 21:09






  • 6





    This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

    – T.C.
    Apr 30 at 2:17
















Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

– Barry
Apr 29 at 20:36





Wouldn't this reasoning imply that a hypothetical if constexpr (makeFalse<decltype(type)>) type.x(); would not be discarded either?

– Barry
Apr 29 at 20:36













@Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

– cpplearner
Apr 29 at 20:52






@Barry Yes. But type.x() is a dependent and possibly valid expression after the instantiation.

– cpplearner
Apr 29 at 20:52














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
Apr 29 at 20:56





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
Apr 29 at 20:56




5




5





@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
Apr 29 at 21:09





@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
Apr 29 at 21:09




6




6





This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

– T.C.
Apr 30 at 2:17





This is equivalent to the motivating example of P0588R0, except that there's not even an implicit capture that could complicate things under the old rules.

– T.C.
Apr 30 at 2:17



















draft saved

draft discarded
















































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.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55909018%2fan-if-constexpr-branch-does-not-get-discarded-inside-lambda-that-is-inside-a-t%23new-answer', 'question_page');

);

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







Popular posts from this blog

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?