Will consteval functions allow template parameters dependent on function arguments?Use 'class' or 'typename' for template parameters?Why can templates only be implemented in the header file?Possible to instantiate templates using a for loop in a C++14 constexpr function?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsenum to string in modern C++11 / C++14 / C++17 and future C++20Implementing is_constexpr_copiableIs it possible to know when is constexpr really a constexpr?Size of std::array in class template depending on template parameterif vs if constexpr inside constexpr functionAre floating point operations resulting in infinity undefined behavior for IEC 559/IEEE 754 floating-point types

Old short story, same personalities, differing planes of existence

Why doesn't the Earth's acceleration towards the Moon accumulate to push the Earth off its orbit?

Riley Rebuses that Share a Common Theme

Placing bypass capacitors after VCC reaches the IC

How to make a crossed out leftrightarrow?

Is there a general effective method to solve Smullyan style Knights and Knaves problems? Is the truth table method the most appropriate one?

Binary Search in C++17

Would jet fuel for an F-16 or F-35 be producible during WW2?

Why is this Simple Puzzle impossible to solve?

Employer demanding to see degree after poor code review

At what point in European history could a government build a printing press given a basic description?

Mother abusing my finances

Were pens caps holes designed to prevent death by suffocation if swallowed?

Is there a public standard for 8 and 10 character grid locators?

Should breaking down something like a door be adjudicated as an attempt to beat its AC and HP, or as an ability check against a set DC?

Employer asking for online access to bank account - Is this a scam?

How did early x86 BIOS programmers manage to program full blown TUIs given very few bytes of ROM/EPROM?

Is this resistor leaking? If so, is it a concern?

I think I may have violated academic integrity last year - what should I do?

How were these pictures of spacecraft wind tunnel testing taken?

What is the object moving across the ceiling in this stock footage?

I unknowingly submitted plagiarised work

How to prevent bad sectors?

ESTA/WVP - leaving US within 90 days, then staying in DR



Will consteval functions allow template parameters dependent on function arguments?


Use 'class' or 'typename' for template parameters?Why can templates only be implemented in the header file?Possible to instantiate templates using a for loop in a C++14 constexpr function?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsenum to string in modern C++11 / C++14 / C++17 and future C++20Implementing is_constexpr_copiableIs it possible to know when is constexpr really a constexpr?Size of std::array in class template depending on template parameterif vs if constexpr inside constexpr functionAre floating point operations resulting in infinity undefined behavior for IEC 559/IEEE 754 floating-point types






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








46















In C++17, this code is illegal:



constexpr int foo(int i) 
return std::integral_constant<int, i>::value;



That's because even if foo can be evaluated at compile-time, the compiler still needs to produce the instructions to execute it at runtime, thus making the template instantiation impossible.



In C++20 we will have consteval functions, which are required to be evaluated at compile-time, so the runtime constraint should be removed. Does it mean this code will be legal?



consteval int foo(int i) 
return std::integral_constant<int, i>::value;










share|improve this question
























  • AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

    – L. F.
    May 14 at 12:59






  • 1





    cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

    – NathanOliver
    May 14 at 13:01

















46















In C++17, this code is illegal:



constexpr int foo(int i) 
return std::integral_constant<int, i>::value;



That's because even if foo can be evaluated at compile-time, the compiler still needs to produce the instructions to execute it at runtime, thus making the template instantiation impossible.



In C++20 we will have consteval functions, which are required to be evaluated at compile-time, so the runtime constraint should be removed. Does it mean this code will be legal?



consteval int foo(int i) 
return std::integral_constant<int, i>::value;










share|improve this question
























  • AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

    – L. F.
    May 14 at 12:59






  • 1





    cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

    – NathanOliver
    May 14 at 13:01













46












46








46


3






In C++17, this code is illegal:



constexpr int foo(int i) 
return std::integral_constant<int, i>::value;



That's because even if foo can be evaluated at compile-time, the compiler still needs to produce the instructions to execute it at runtime, thus making the template instantiation impossible.



In C++20 we will have consteval functions, which are required to be evaluated at compile-time, so the runtime constraint should be removed. Does it mean this code will be legal?



consteval int foo(int i) 
return std::integral_constant<int, i>::value;










share|improve this question
















In C++17, this code is illegal:



constexpr int foo(int i) 
return std::integral_constant<int, i>::value;



That's because even if foo can be evaluated at compile-time, the compiler still needs to produce the instructions to execute it at runtime, thus making the template instantiation impossible.



In C++20 we will have consteval functions, which are required to be evaluated at compile-time, so the runtime constraint should be removed. Does it mean this code will be legal?



consteval int foo(int i) 
return std::integral_constant<int, i>::value;







c++ language-lawyer constexpr c++20 class-template






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 14 at 16:40









curiousguy

4,77623046




4,77623046










asked May 14 at 12:43









AnnyoAnnyo

482111




482111












  • AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

    – L. F.
    May 14 at 12:59






  • 1





    cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

    – NathanOliver
    May 14 at 13:01

















  • AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

    – L. F.
    May 14 at 12:59






  • 1





    cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

    – NathanOliver
    May 14 at 13:01
















AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

– L. F.
May 14 at 12:59





AFAIK, no. i is (yet) not considered a core constant expression at that very moment.

– L. F.
May 14 at 12:59




1




1





cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

– NathanOliver
May 14 at 13:01





cppreference has The consteval specifier declares a function or function template to be an immediate function [...] An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be. so signs point to no. My reading of the standard leads me to the same conclusion but I'm not certain enough to state that in an answer.

– NathanOliver
May 14 at 13:01












3 Answers
3






active

oldest

votes


















30














No.



Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-temploid function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.



The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;



consteval int sqrsqr(int n) 
return sqr(sqr(n)); // Not a constant-expression at this point,
// but that's okay.



In short, function parameters will never be constant expressions, due to possible typing discrepancy.






share|improve this answer

























  • Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

    – Nicol Bolas
    May 14 at 13:31











  • @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

    – Columbo
    May 14 at 13:47


















23















Does it mean this code will be legal?



consteval int foo(int i) 
return std::integral_constant<int, i>::value;




No. This is still ill-formed. While consteval requires the call itself to be a constant expression, so you know that the argument that produces i must be a constant expression, foo itself is still not a template. Template?



A slight variation in your example might make this more obvious:



consteval auto foo(int i) 
return std::integral_constant<int, i>();



Were this to be valid, foo(1) and foo(2) would... return different types. This is an entirely different language feature (constexpr function parameters) - because in order for this to work, such functions would really need to behave like templates.



It may seem a little unintuitive. After all, if the argument that produced i was a constant expression, surely i should be usable as one as well? But it's still not - there are no additional exceptions in [expr.const] that permit parameters for immediate functions. An immediate function is still just a function, and its parameters still aren't constant expressions -- in the same way that a normal constexpr function's parameters aren't constant expressions.




Of course with int, we can just rewrite the function to lift the function parameter into a template parameter:



template <int i>
consteval int foo()
return std::integral_constant<int, i>::value;



And C++20 gives us class types as non-type template parameters, so we can actually do this for many more types than we could before. But there are still plenty of types that we could use as a parameter to an immediate function that we cannot use as a template parameter - so this won't always work (e.g. std::optional or, more excitingly in C++20, std::string).






share|improve this answer

























  • 190k? They have a low pressure environment at Jump, yeah? ;-)

    – Columbo
    May 14 at 13:28











  • @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

    – Barry
    May 14 at 13:31











  • Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

    – Columbo
    May 14 at 13:46












  • Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

    – Ruslan
    May 14 at 13:48







  • 1





    @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

    – Columbo
    May 14 at 13:49


















7














It would seem that this will not be legal in C++20. A good explanation for why this would be problematic to support has already been given in the answers by @Barry and @Columbo (it doesn't really work with the type system). I'll just add what I believe to be the relevant quotes from the standard here that actually make this illegal.



Based on [temp.arg.nontype]/2




A template-argument for a non-type template-parameter shall be a converted constant expression […]




A converted constant expression is a constant expression that is implicitly converted to a particular type [expr.const]/7 (here, the type of the template parameter). So your question boils down to the question of whether a variable inside a consteval function is a constant expression. Based on [expr.const]/8




A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints: […]




The expression i is a glvalue id-expression that is a core constant expression (because its evaluation does not do any of the things listed in [expr.const]/4). However, the entity this core constant expression refers to is not a permitted result of a constant expression [expr.const]/8:




An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.




The object in question is neither of static storage duration nor is it a temporary object…






share|improve this answer

























    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%2f56130792%2fwill-consteval-functions-allow-template-parameters-dependent-on-function-argumen%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    30














    No.



    Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-temploid function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.



    The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;



    consteval int sqrsqr(int n) 
    return sqr(sqr(n)); // Not a constant-expression at this point,
    // but that's okay.



    In short, function parameters will never be constant expressions, due to possible typing discrepancy.






    share|improve this answer

























    • Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

      – Nicol Bolas
      May 14 at 13:31











    • @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

      – Columbo
      May 14 at 13:47















    30














    No.



    Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-temploid function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.



    The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;



    consteval int sqrsqr(int n) 
    return sqr(sqr(n)); // Not a constant-expression at this point,
    // but that's okay.



    In short, function parameters will never be constant expressions, due to possible typing discrepancy.






    share|improve this answer

























    • Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

      – Nicol Bolas
      May 14 at 13:31











    • @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

      – Columbo
      May 14 at 13:47













    30












    30








    30







    No.



    Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-temploid function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.



    The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;



    consteval int sqrsqr(int n) 
    return sqr(sqr(n)); // Not a constant-expression at this point,
    // but that's okay.



    In short, function parameters will never be constant expressions, due to possible typing discrepancy.






    share|improve this answer















    No.



    Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-temploid function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.



    The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;



    consteval int sqrsqr(int n) 
    return sqr(sqr(n)); // Not a constant-expression at this point,
    // but that's okay.



    In short, function parameters will never be constant expressions, due to possible typing discrepancy.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 14 at 13:23

























    answered May 14 at 13:16









    ColumboColumbo

    53.5k7127182




    53.5k7127182












    • Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

      – Nicol Bolas
      May 14 at 13:31











    • @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

      – Columbo
      May 14 at 13:47

















    • Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

      – Nicol Bolas
      May 14 at 13:31











    • @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

      – Columbo
      May 14 at 13:47
















    Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

    – Nicol Bolas
    May 14 at 13:31





    Note that it does allow you to pass an argument of a consteval function to another consteval function, even though the argument is not technically a constant expression.

    – Nicol Bolas
    May 14 at 13:31













    @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

    – Columbo
    May 14 at 13:47





    @NicolBolas That's by permission on the side of immediate functions though, not on the side of the arguments. As you said: those aren't constant expressions, and template parameters require those for good reason.

    – Columbo
    May 14 at 13:47













    23















    Does it mean this code will be legal?



    consteval int foo(int i) 
    return std::integral_constant<int, i>::value;




    No. This is still ill-formed. While consteval requires the call itself to be a constant expression, so you know that the argument that produces i must be a constant expression, foo itself is still not a template. Template?



    A slight variation in your example might make this more obvious:



    consteval auto foo(int i) 
    return std::integral_constant<int, i>();



    Were this to be valid, foo(1) and foo(2) would... return different types. This is an entirely different language feature (constexpr function parameters) - because in order for this to work, such functions would really need to behave like templates.



    It may seem a little unintuitive. After all, if the argument that produced i was a constant expression, surely i should be usable as one as well? But it's still not - there are no additional exceptions in [expr.const] that permit parameters for immediate functions. An immediate function is still just a function, and its parameters still aren't constant expressions -- in the same way that a normal constexpr function's parameters aren't constant expressions.




    Of course with int, we can just rewrite the function to lift the function parameter into a template parameter:



    template <int i>
    consteval int foo()
    return std::integral_constant<int, i>::value;



    And C++20 gives us class types as non-type template parameters, so we can actually do this for many more types than we could before. But there are still plenty of types that we could use as a parameter to an immediate function that we cannot use as a template parameter - so this won't always work (e.g. std::optional or, more excitingly in C++20, std::string).






    share|improve this answer

























    • 190k? They have a low pressure environment at Jump, yeah? ;-)

      – Columbo
      May 14 at 13:28











    • @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

      – Barry
      May 14 at 13:31











    • Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

      – Columbo
      May 14 at 13:46












    • Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

      – Ruslan
      May 14 at 13:48







    • 1





      @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

      – Columbo
      May 14 at 13:49















    23















    Does it mean this code will be legal?



    consteval int foo(int i) 
    return std::integral_constant<int, i>::value;




    No. This is still ill-formed. While consteval requires the call itself to be a constant expression, so you know that the argument that produces i must be a constant expression, foo itself is still not a template. Template?



    A slight variation in your example might make this more obvious:



    consteval auto foo(int i) 
    return std::integral_constant<int, i>();



    Were this to be valid, foo(1) and foo(2) would... return different types. This is an entirely different language feature (constexpr function parameters) - because in order for this to work, such functions would really need to behave like templates.



    It may seem a little unintuitive. After all, if the argument that produced i was a constant expression, surely i should be usable as one as well? But it's still not - there are no additional exceptions in [expr.const] that permit parameters for immediate functions. An immediate function is still just a function, and its parameters still aren't constant expressions -- in the same way that a normal constexpr function's parameters aren't constant expressions.




    Of course with int, we can just rewrite the function to lift the function parameter into a template parameter:



    template <int i>
    consteval int foo()
    return std::integral_constant<int, i>::value;



    And C++20 gives us class types as non-type template parameters, so we can actually do this for many more types than we could before. But there are still plenty of types that we could use as a parameter to an immediate function that we cannot use as a template parameter - so this won't always work (e.g. std::optional or, more excitingly in C++20, std::string).






    share|improve this answer

























    • 190k? They have a low pressure environment at Jump, yeah? ;-)

      – Columbo
      May 14 at 13:28











    • @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

      – Barry
      May 14 at 13:31











    • Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

      – Columbo
      May 14 at 13:46












    • Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

      – Ruslan
      May 14 at 13:48







    • 1





      @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

      – Columbo
      May 14 at 13:49













    23












    23








    23








    Does it mean this code will be legal?



    consteval int foo(int i) 
    return std::integral_constant<int, i>::value;




    No. This is still ill-formed. While consteval requires the call itself to be a constant expression, so you know that the argument that produces i must be a constant expression, foo itself is still not a template. Template?



    A slight variation in your example might make this more obvious:



    consteval auto foo(int i) 
    return std::integral_constant<int, i>();



    Were this to be valid, foo(1) and foo(2) would... return different types. This is an entirely different language feature (constexpr function parameters) - because in order for this to work, such functions would really need to behave like templates.



    It may seem a little unintuitive. After all, if the argument that produced i was a constant expression, surely i should be usable as one as well? But it's still not - there are no additional exceptions in [expr.const] that permit parameters for immediate functions. An immediate function is still just a function, and its parameters still aren't constant expressions -- in the same way that a normal constexpr function's parameters aren't constant expressions.




    Of course with int, we can just rewrite the function to lift the function parameter into a template parameter:



    template <int i>
    consteval int foo()
    return std::integral_constant<int, i>::value;



    And C++20 gives us class types as non-type template parameters, so we can actually do this for many more types than we could before. But there are still plenty of types that we could use as a parameter to an immediate function that we cannot use as a template parameter - so this won't always work (e.g. std::optional or, more excitingly in C++20, std::string).






    share|improve this answer
















    Does it mean this code will be legal?



    consteval int foo(int i) 
    return std::integral_constant<int, i>::value;




    No. This is still ill-formed. While consteval requires the call itself to be a constant expression, so you know that the argument that produces i must be a constant expression, foo itself is still not a template. Template?



    A slight variation in your example might make this more obvious:



    consteval auto foo(int i) 
    return std::integral_constant<int, i>();



    Were this to be valid, foo(1) and foo(2) would... return different types. This is an entirely different language feature (constexpr function parameters) - because in order for this to work, such functions would really need to behave like templates.



    It may seem a little unintuitive. After all, if the argument that produced i was a constant expression, surely i should be usable as one as well? But it's still not - there are no additional exceptions in [expr.const] that permit parameters for immediate functions. An immediate function is still just a function, and its parameters still aren't constant expressions -- in the same way that a normal constexpr function's parameters aren't constant expressions.




    Of course with int, we can just rewrite the function to lift the function parameter into a template parameter:



    template <int i>
    consteval int foo()
    return std::integral_constant<int, i>::value;



    And C++20 gives us class types as non-type template parameters, so we can actually do this for many more types than we could before. But there are still plenty of types that we could use as a parameter to an immediate function that we cannot use as a template parameter - so this won't always work (e.g. std::optional or, more excitingly in C++20, std::string).







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 14 at 13:17

























    answered May 14 at 13:12









    BarryBarry

    191k21342628




    191k21342628












    • 190k? They have a low pressure environment at Jump, yeah? ;-)

      – Columbo
      May 14 at 13:28











    • @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

      – Barry
      May 14 at 13:31











    • Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

      – Columbo
      May 14 at 13:46












    • Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

      – Ruslan
      May 14 at 13:48







    • 1





      @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

      – Columbo
      May 14 at 13:49

















    • 190k? They have a low pressure environment at Jump, yeah? ;-)

      – Columbo
      May 14 at 13:28











    • @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

      – Barry
      May 14 at 13:31











    • Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

      – Columbo
      May 14 at 13:46












    • Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

      – Ruslan
      May 14 at 13:48







    • 1





      @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

      – Columbo
      May 14 at 13:49
















    190k? They have a low pressure environment at Jump, yeah? ;-)

    – Columbo
    May 14 at 13:28





    190k? They have a low pressure environment at Jump, yeah? ;-)

    – Columbo
    May 14 at 13:28













    @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

    – Barry
    May 14 at 13:31





    @Columbo I've missed you man, somebody's gotta pick up the slack. How's HRT treating you?

    – Barry
    May 14 at 13:31













    Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

    – Columbo
    May 14 at 13:46






    Very well, and I trust the same holds for you. I've been gone for too long—worklife needs getting used to. Hope to be more active going forward! :-) Do you happen to attend WG21 meetings by now?

    – Columbo
    May 14 at 13:46














    Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

    – Ruslan
    May 14 at 13:48






    Can't we use a helper like consteval int to_constexpr(int x) return x; , and then return std::integral_constant<int, to_constexpr(i)>::value; from (the non-templated version of) foo()? If yes, then current non-constexpr'ness of parameters looks like a useless restriction.

    – Ruslan
    May 14 at 13:48





    1




    1





    @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

    – Columbo
    May 14 at 13:49





    @Ruslan No. Because to_constexpr(x) is not a constant expression, which is allowed as it's inside a consteval function definition.

    – Columbo
    May 14 at 13:49











    7














    It would seem that this will not be legal in C++20. A good explanation for why this would be problematic to support has already been given in the answers by @Barry and @Columbo (it doesn't really work with the type system). I'll just add what I believe to be the relevant quotes from the standard here that actually make this illegal.



    Based on [temp.arg.nontype]/2




    A template-argument for a non-type template-parameter shall be a converted constant expression […]




    A converted constant expression is a constant expression that is implicitly converted to a particular type [expr.const]/7 (here, the type of the template parameter). So your question boils down to the question of whether a variable inside a consteval function is a constant expression. Based on [expr.const]/8




    A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints: […]




    The expression i is a glvalue id-expression that is a core constant expression (because its evaluation does not do any of the things listed in [expr.const]/4). However, the entity this core constant expression refers to is not a permitted result of a constant expression [expr.const]/8:




    An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.




    The object in question is neither of static storage duration nor is it a temporary object…






    share|improve this answer





























      7














      It would seem that this will not be legal in C++20. A good explanation for why this would be problematic to support has already been given in the answers by @Barry and @Columbo (it doesn't really work with the type system). I'll just add what I believe to be the relevant quotes from the standard here that actually make this illegal.



      Based on [temp.arg.nontype]/2




      A template-argument for a non-type template-parameter shall be a converted constant expression […]




      A converted constant expression is a constant expression that is implicitly converted to a particular type [expr.const]/7 (here, the type of the template parameter). So your question boils down to the question of whether a variable inside a consteval function is a constant expression. Based on [expr.const]/8




      A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints: […]




      The expression i is a glvalue id-expression that is a core constant expression (because its evaluation does not do any of the things listed in [expr.const]/4). However, the entity this core constant expression refers to is not a permitted result of a constant expression [expr.const]/8:




      An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.




      The object in question is neither of static storage duration nor is it a temporary object…






      share|improve this answer



























        7












        7








        7







        It would seem that this will not be legal in C++20. A good explanation for why this would be problematic to support has already been given in the answers by @Barry and @Columbo (it doesn't really work with the type system). I'll just add what I believe to be the relevant quotes from the standard here that actually make this illegal.



        Based on [temp.arg.nontype]/2




        A template-argument for a non-type template-parameter shall be a converted constant expression […]




        A converted constant expression is a constant expression that is implicitly converted to a particular type [expr.const]/7 (here, the type of the template parameter). So your question boils down to the question of whether a variable inside a consteval function is a constant expression. Based on [expr.const]/8




        A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints: […]




        The expression i is a glvalue id-expression that is a core constant expression (because its evaluation does not do any of the things listed in [expr.const]/4). However, the entity this core constant expression refers to is not a permitted result of a constant expression [expr.const]/8:




        An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.




        The object in question is neither of static storage duration nor is it a temporary object…






        share|improve this answer















        It would seem that this will not be legal in C++20. A good explanation for why this would be problematic to support has already been given in the answers by @Barry and @Columbo (it doesn't really work with the type system). I'll just add what I believe to be the relevant quotes from the standard here that actually make this illegal.



        Based on [temp.arg.nontype]/2




        A template-argument for a non-type template-parameter shall be a converted constant expression […]




        A converted constant expression is a constant expression that is implicitly converted to a particular type [expr.const]/7 (here, the type of the template parameter). So your question boils down to the question of whether a variable inside a consteval function is a constant expression. Based on [expr.const]/8




        A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints: […]




        The expression i is a glvalue id-expression that is a core constant expression (because its evaluation does not do any of the things listed in [expr.const]/4). However, the entity this core constant expression refers to is not a permitted result of a constant expression [expr.const]/8:




        An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.




        The object in question is neither of static storage duration nor is it a temporary object…







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 14 at 13:36

























        answered May 14 at 13:18









        Michael KenzelMichael Kenzel

        10.6k11926




        10.6k11926



























            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%2f56130792%2fwill-consteval-functions-allow-template-parameters-dependent-on-function-argumen%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

            Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

            Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

            Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020