An 'if constexpr branch' does not get discarded inside lambda that is inside a template functionC++0x error...

Does hiding behind 5-ft-wide cover give full cover?

Power LED from 3.3V Power Pin without Resistor

Map one pandas column using two dictionaries

How can I fairly adjudicate the effects of height differences on ranged attacks?

Historically, were women trained for obligatory wars? Or did they serve some other military function?

Was the ancestor of SCSI, the SASI protocol, nothing more than a draft?

I lost my Irish passport. Can I travel to Thailand and back from the UK using my US passport?

Why is Arya visibly scared in the library in S8E3?

How did Arya manage to disguise herself?

How do I tell my manager that his code review comment is wrong?

Selecting a secure PIN for building access

How to implement float hashing with approximate equality

Problems with numbers (result of calculations) alignment using siunitx package inside tabular environment

Game of Life meets Chaos Theory

Why do money exchangers give different rates to different bills

Short story about people living in a different time streams

If 1. e4 c6 is considered as a sound defense for black, why is 1. c3 so rare?

I caught several of my students plagiarizing. Could it be my fault as a teacher?

How to efficiently calculate prefix sum of frequencies of characters in a string?

Is lying to get "gardening leave" fraud?

Is it the same airport YUL and YMQ in Canada?

If I supply 24v to a 50v rated 22000uf electrolytic capacitor, does that mean it will store 44000uf at 24v?

How to creep the reader out with what seems like a normal person?

Does the time required to copy a spell into a spellbook have to be consecutive, or is that just the cumulative time required?



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







17















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


















17















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














17












17








17


5






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 24 mins ago









Peter Mortensen

14k1987114




14k1987114










asked 5 hours ago









nicolainicolai

331211




331211













  • 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








  • 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











  • (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












1 Answer
1






active

oldest

votes


















10














[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
    3 hours ago











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

    – cpplearner
    3 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
    3 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 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












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









10














[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
    3 hours ago











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

    – cpplearner
    3 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
    3 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 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
















10














[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
    3 hours ago











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

    – cpplearner
    3 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
    3 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 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














10












10








10







[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 4 hours ago









cpplearnercpplearner

6,23122543




6,23122543













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

    – Barry
    3 hours ago











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

    – cpplearner
    3 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
    3 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 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



















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

    – Barry
    3 hours ago











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

    – cpplearner
    3 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
    3 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 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

















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

– Barry
3 hours ago





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

– Barry
3 hours ago













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

– cpplearner
3 hours ago







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

– cpplearner
3 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
3 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
3 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




















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

Gersau Kjelder | Navigasjonsmeny46°59′0″N 8°31′0″E46°59′0″N...

Hestehale Innhaldsliste Hestehale på kvinner | Hestehale på menn | Galleri | Sjå òg |...

What is the “three and three hundred thousand syndrome”?Who wrote the book Arena?What five creatures were...