Do I need to put constexpr after else-if?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite












Inspired by this answer, I tried to copy and paste (and add testing in main()) this code:



template<typename T>
std::tuple<int, double> foo(T a)
if constexpr (std::is_same_v<int, T>)
return a, 0.0;

else if (std::is_same_v<double, T>)
return 0, a;

else
return 0, 0.0;


int main()

auto [x, y] = foo("");

std::cout << x << " " << y;



This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0].



As you can see, in the main() function, I am calling foo with const char* argument, which should result in x and y being 0. That is not the case.



While trying to compile it, I encountered a strange error:




error: could not convert '0, a' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'




And I was like what?. Why on earth would I want that... I specifically used std::is_same to enable return 0, a only when the type of a is deduced as double.



So I quickly ran to cppreference on if-constexpr. At the bottom of the page, above Notes, we can see this snippet of code:



extern int x; // no definition of x required
int f()
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;



I thought to myself oookay..? I can't really see what's wrong with the original code. They use the same syntax and semantics....



But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:



template<typename T>
std::tuple<int, double> foo(T a)
if constexpr (std::is_same_v<int, T>)
return a, 0.0;

else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
return 0, a;

else
return 0, 0.0;


int main()

auto [x, y] = foo("");

std::cout << x << " " << y;



And voilà! The code compiled and executed as expected. So, my question is - Do we need to put constexpr after every if statement in if-else block in these kind of situations? Or is it just my compiler? I am using GCC 7.3.










share|improve this question

























    up vote
    6
    down vote

    favorite












    Inspired by this answer, I tried to copy and paste (and add testing in main()) this code:



    template<typename T>
    std::tuple<int, double> foo(T a)
    if constexpr (std::is_same_v<int, T>)
    return a, 0.0;

    else if (std::is_same_v<double, T>)
    return 0, a;

    else
    return 0, 0.0;


    int main()

    auto [x, y] = foo("");

    std::cout << x << " " << y;



    This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0].



    As you can see, in the main() function, I am calling foo with const char* argument, which should result in x and y being 0. That is not the case.



    While trying to compile it, I encountered a strange error:




    error: could not convert '0, a' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'




    And I was like what?. Why on earth would I want that... I specifically used std::is_same to enable return 0, a only when the type of a is deduced as double.



    So I quickly ran to cppreference on if-constexpr. At the bottom of the page, above Notes, we can see this snippet of code:



    extern int x; // no definition of x required
    int f()
    if constexpr (true)
    return 0;
    else if (x)
    return x;
    else
    return -x;



    I thought to myself oookay..? I can't really see what's wrong with the original code. They use the same syntax and semantics....



    But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:



    template<typename T>
    std::tuple<int, double> foo(T a)
    if constexpr (std::is_same_v<int, T>)
    return a, 0.0;

    else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
    return 0, a;

    else
    return 0, 0.0;


    int main()

    auto [x, y] = foo("");

    std::cout << x << " " << y;



    And voilà! The code compiled and executed as expected. So, my question is - Do we need to put constexpr after every if statement in if-else block in these kind of situations? Or is it just my compiler? I am using GCC 7.3.










    share|improve this question























      up vote
      6
      down vote

      favorite









      up vote
      6
      down vote

      favorite











      Inspired by this answer, I tried to copy and paste (and add testing in main()) this code:



      template<typename T>
      std::tuple<int, double> foo(T a)
      if constexpr (std::is_same_v<int, T>)
      return a, 0.0;

      else if (std::is_same_v<double, T>)
      return 0, a;

      else
      return 0, 0.0;


      int main()

      auto [x, y] = foo("");

      std::cout << x << " " << y;



      This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0].



      As you can see, in the main() function, I am calling foo with const char* argument, which should result in x and y being 0. That is not the case.



      While trying to compile it, I encountered a strange error:




      error: could not convert '0, a' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'




      And I was like what?. Why on earth would I want that... I specifically used std::is_same to enable return 0, a only when the type of a is deduced as double.



      So I quickly ran to cppreference on if-constexpr. At the bottom of the page, above Notes, we can see this snippet of code:



      extern int x; // no definition of x required
      int f()
      if constexpr (true)
      return 0;
      else if (x)
      return x;
      else
      return -x;



      I thought to myself oookay..? I can't really see what's wrong with the original code. They use the same syntax and semantics....



      But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:



      template<typename T>
      std::tuple<int, double> foo(T a)
      if constexpr (std::is_same_v<int, T>)
      return a, 0.0;

      else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
      return 0, a;

      else
      return 0, 0.0;


      int main()

      auto [x, y] = foo("");

      std::cout << x << " " << y;



      And voilà! The code compiled and executed as expected. So, my question is - Do we need to put constexpr after every if statement in if-else block in these kind of situations? Or is it just my compiler? I am using GCC 7.3.










      share|improve this question













      Inspired by this answer, I tried to copy and paste (and add testing in main()) this code:



      template<typename T>
      std::tuple<int, double> foo(T a)
      if constexpr (std::is_same_v<int, T>)
      return a, 0.0;

      else if (std::is_same_v<double, T>)
      return 0, a;

      else
      return 0, 0.0;


      int main()

      auto [x, y] = foo("");

      std::cout << x << " " << y;



      This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0].



      As you can see, in the main() function, I am calling foo with const char* argument, which should result in x and y being 0. That is not the case.



      While trying to compile it, I encountered a strange error:




      error: could not convert '0, a' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'




      And I was like what?. Why on earth would I want that... I specifically used std::is_same to enable return 0, a only when the type of a is deduced as double.



      So I quickly ran to cppreference on if-constexpr. At the bottom of the page, above Notes, we can see this snippet of code:



      extern int x; // no definition of x required
      int f()
      if constexpr (true)
      return 0;
      else if (x)
      return x;
      else
      return -x;



      I thought to myself oookay..? I can't really see what's wrong with the original code. They use the same syntax and semantics....



      But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:



      template<typename T>
      std::tuple<int, double> foo(T a)
      if constexpr (std::is_same_v<int, T>)
      return a, 0.0;

      else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
      return 0, a;

      else
      return 0, 0.0;


      int main()

      auto [x, y] = foo("");

      std::cout << x << " " << y;



      And voilà! The code compiled and executed as expected. So, my question is - Do we need to put constexpr after every if statement in if-else block in these kind of situations? Or is it just my compiler? I am using GCC 7.3.







      c++ if-statement c++17 if-constexpr






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 1 hour ago









      Fureeish

      1,9951719




      1,9951719






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          9
          down vote



          accepted











          Do we need to put constexpr after every if statement in if-else block in these kind of situations?




          Yes. The else-if block is a lie :), there are only if blocks and else blocks. This is how your code is seen by the compiler:



          if constexpr (std::is_same_v<int, T>)
          return a, 0.0;
          else //
          if (std::is_same_v<double, T>)
          return 0, a;
          else
          return 0, 0.0;
          //


          else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.






          share|improve this answer
















          • 1




            Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
            – Fureeish
            1 hour ago







          • 3




            @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
            – Rakete1111
            1 hour ago










          • Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
            – Marek R
            1 hour ago










          • @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
            – Rakete1111
            1 hour ago










          • Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
            – Fureeish
            1 hour 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',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          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%2f52356341%2fdo-i-need-to-put-constexpr-after-else-if%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          9
          down vote



          accepted











          Do we need to put constexpr after every if statement in if-else block in these kind of situations?




          Yes. The else-if block is a lie :), there are only if blocks and else blocks. This is how your code is seen by the compiler:



          if constexpr (std::is_same_v<int, T>)
          return a, 0.0;
          else //
          if (std::is_same_v<double, T>)
          return 0, a;
          else
          return 0, 0.0;
          //


          else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.






          share|improve this answer
















          • 1




            Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
            – Fureeish
            1 hour ago







          • 3




            @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
            – Rakete1111
            1 hour ago










          • Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
            – Marek R
            1 hour ago










          • @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
            – Rakete1111
            1 hour ago










          • Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
            – Fureeish
            1 hour ago














          up vote
          9
          down vote



          accepted











          Do we need to put constexpr after every if statement in if-else block in these kind of situations?




          Yes. The else-if block is a lie :), there are only if blocks and else blocks. This is how your code is seen by the compiler:



          if constexpr (std::is_same_v<int, T>)
          return a, 0.0;
          else //
          if (std::is_same_v<double, T>)
          return 0, a;
          else
          return 0, 0.0;
          //


          else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.






          share|improve this answer
















          • 1




            Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
            – Fureeish
            1 hour ago







          • 3




            @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
            – Rakete1111
            1 hour ago










          • Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
            – Marek R
            1 hour ago










          • @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
            – Rakete1111
            1 hour ago










          • Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
            – Fureeish
            1 hour ago












          up vote
          9
          down vote



          accepted







          up vote
          9
          down vote



          accepted







          Do we need to put constexpr after every if statement in if-else block in these kind of situations?




          Yes. The else-if block is a lie :), there are only if blocks and else blocks. This is how your code is seen by the compiler:



          if constexpr (std::is_same_v<int, T>)
          return a, 0.0;
          else //
          if (std::is_same_v<double, T>)
          return 0, a;
          else
          return 0, 0.0;
          //


          else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.






          share|improve this answer













          Do we need to put constexpr after every if statement in if-else block in these kind of situations?




          Yes. The else-if block is a lie :), there are only if blocks and else blocks. This is how your code is seen by the compiler:



          if constexpr (std::is_same_v<int, T>)
          return a, 0.0;
          else //
          if (std::is_same_v<double, T>)
          return 0, a;
          else
          return 0, 0.0;
          //


          else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 1 hour ago









          Rakete1111

          32.2k973108




          32.2k973108







          • 1




            Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
            – Fureeish
            1 hour ago







          • 3




            @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
            – Rakete1111
            1 hour ago










          • Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
            – Marek R
            1 hour ago










          • @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
            – Rakete1111
            1 hour ago










          • Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
            – Fureeish
            1 hour ago












          • 1




            Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
            – Fureeish
            1 hour ago







          • 3




            @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
            – Rakete1111
            1 hour ago










          • Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
            – Marek R
            1 hour ago










          • @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
            – Rakete1111
            1 hour ago










          • Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
            – Fureeish
            1 hour ago







          1




          1




          Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
          – Fureeish
          1 hour ago





          Thank you! So now it's time to correct the original piece of code that made me come across this. Gonna accept the answer asap
          – Fureeish
          1 hour ago





          3




          3




          @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
          – Rakete1111
          1 hour ago




          @Fureeish Also note the cppref's example is correct, the missing constexpr is there by design to show that you don't have to have a definition of x because the else block (see answer) is discarded.
          – Rakete1111
          1 hour ago












          Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
          – Marek R
          1 hour ago




          Question: Defining function foo as constexpr will make everything inside a constexpr or still all ifs should be decorated with constexpr?
          – Marek R
          1 hour ago












          @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
          – Rakete1111
          1 hour ago




          @MarekR The inner if's still need to be decorated. Just because foo is constexpr doesn't mean that everything inside the function is constexpr (as you can still call the function at runtime).
          – Rakete1111
          1 hour ago












          Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
          – Fureeish
          1 hour ago




          Defining a function foo as constexpr will simply make it possible to be evaluated at compile time. You still need to use constexpr inside it to achieve the same goals
          – Fureeish
          1 hour ago

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52356341%2fdo-i-need-to-put-constexpr-after-else-if%23new-answer', 'question_page');

          );

          Post as a guest













































































          Comments

          Popular posts from this blog

          Long meetings (6-7 hours a day): Being “babysat” by supervisor

          Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

          Confectionery