Introduction
C 17 introduced the if constexpr keyword, allowing conditional compilation based on compile-time constants. However, unexpected errors can arise when using if constexpr in non-templated functions. This article explores these issues and provides a solution.
Code Example
Consider the following code:
<code class="cpp">#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; }
Compilation Error
This code generates a compilation error when the if constexpr statement is within the main function:
main.cpp:8:32: error: invalid type argument of unary ‘*’ (have ‘int’) std::cout << "Ptr to " << *value << std::endl;
Explanation
If constexpr only works in template functions because it allows the compiler to avoid instantiating branches that are not taken at compile time. This optimization is essential for efficient template metaprogramming.
In non-templated functions, if constexpr still evaluates both branches, even if the type is deduced by decltype. This means that the error in the code above is caused by the attempt to dereference an int value in the if branch.
Solution
To resolve this issue, you can move the if constexpr statement into a template function. For example:
<code class="cpp">template <typename T> void print(T value) { if constexpr (std::is_pointer_v<decltype(value)>) std::cout << "Ptr to " << *value << std::endl; else std::cout << "Ref to " << value << std::endl; } int main() { auto value = 100; print(value); }</code>
This modified code will compile and print the expected output:
Ref to 100
The above is the detailed content of Why does 'if constexpr' cause errors in non-templated functions in C 17?. For more information, please follow other related articles on the PHP Chinese website!