“If constexpr” in C++17 does not work in a non-templated function

  • A+
Category:Languages

I tried to play with the C++17 standard. I tried to use one of the features of C++17 "if constexpr". And I had a problem... Please take a look at the following code. This compiles without errors. In the following code, I tried to use "if constexpr" to check if it is a pointer.

#include <iostream> #include <type_traits>  template <typename T> void print(T value) {   if constexpr (std::is_pointer_v<decltype(value)>)     std::cout << "Ptr to " << *value << std::endl; // Ok   else     std::cout << "Ref to " << value << std::endl; }  int main() {   auto n = 1000;   print(n);   print(&n);   return 0; } 

But when I rewrite the above code, as shown below, where "if constexpr" is in the main function, I get a compilation error.

#include <iostream> #include <type_traits>  int main() {   auto value = 100;   if constexpr (std::is_pointer_v<decltype(value)>)     std::cout << "Ptr to " << *value << std::endl; // Error   else     std::cout << "Ref to " << value << std::endl;   return 0; } 

Problem is not in the main function. This can be any function similar to the following.

void print() {   auto value = 100;   if constexpr (std::is_pointer_v<decltype(value)>)     std::cout << "Ptr to " << *value << std::endl; // Error   else     std::cout << "Ref to " << value << std::endl; }  int main() {   print();   return 0; } 

I would like to know why "if constexpr" works only in template functions, even if the type is deduced by the decltype from the input parameter.

Thanks.


I would like to know why "if constexpr" works only in template functions, even if the type is deduced by the decltype from the input parameter.

This is by design.

if constexpr will not instantiate the branch not taken if it's within a template. It won't just treat the branch not taken as token soup and avoid parsing it or performing semantic analysis entirely. Both sides are still going to be analyzed, and since *value is ill-formed for ints, that's an error.

You simply can't use if constexpr to avoid compiling non-template code. It's only to avoid instantiating template code that's potentially invalid-for-the-particular-specialization.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: