问题
C++1z will introduce "constexpr if" - an if that will have one of branches removed, based on the condition. Seems reasonable and useful.
However, is it not possible to do without constexpr keyword? I think that during compilation, compiler should know wheter condition is known during compilation time or not. If it is, even the most basic optimization level should remove unnecessary branch.
For example (see in godbolt: https://godbolt.org/g/IpY5y5):
int test() {
const bool condition = true;
if (condition) {
return 0;
} else {
// optimized out even without "constexpr if"
return 1;
}
}
Godbolt explorer shows, that even gcc-4.4.7 with -O0 did not compile "return 1", so it achieved what was promised with constexpr if. Obviously such old compiler will not be able to do so when condition is result of constexpr function, but fact remains: modern compiler knows whether condition is constexpr or not and doesn't need me to tell it explicitly.
So the question is:
Why is "constexpr" needed in "constexpr if"?
回答1:
This is easy to explain through an example. Consider
struct Cat { void meow() { } };
struct Dog { void bark() { } };
and
template <typename T>
void pet(T x)
{
if(std::is_same<T, Cat>{}){ x.meow(); }
else if(std::is_same<T, Dog>{}){ x.bark(); }
}
Invoking
pet(Cat{});
pet(Dog{});
will trigger a compilation error (wandbox example), because both branches of the if
statement have to be well-formed.
prog.cc:10:40: error: no member named 'bark' in 'Cat'
else if(std::is_same<T, Dog>{}){ x.bark(); }
~ ^
prog.cc:15:5: note: in instantiation of function template specialization 'pet<Cat>' requested here
pet(Cat{});
^
prog.cc:9:35: error: no member named 'meow' in 'Dog'
if(std::is_same<T, Cat>{}){ x.meow(); }
~ ^
prog.cc:16:5: note: in instantiation of function template specialization 'pet<Dog>' requested here
pet(Dog{});
^
Changing pet
to use if constexpr
template <typename T>
void pet(T x)
{
if constexpr(std::is_same<T, Cat>{}){ x.meow(); }
else if constexpr(std::is_same<T, Dog>{}){ x.bark(); }
}
only requires the branches to be parseable - only the branch that matches the condition needs to be well-formed (wandbox example).
The snippet
pet(Cat{});
pet(Dog{});
will compile and work as expected.
来源:https://stackoverflow.com/questions/40972666/constexpr-if-vs-if-with-optimizations-why-is-constexpr-needed