Say we have the following code
struct MyClass
{
MyClass() = delete; // or MyClass() { }
MyClass(int) { }
void func() { }
};
int main()
{
if constexpr (std::is_default_constructible_v<MyClass>) {
MyClass myObj;
} else {
MyClass myObj(10);
}
myObj.func(); // Error
}
Here I am using if constexpr
to determine whether the class is default-constructible (or not), and then create an object accordingly. In a way, I naively thought this would simplify the different branches down to just the one that's true, i.e.
if constexpr (true) {
/* instruction branch 1 */
} else if constexpr (false) {
/* instruction branch 2 */
}
simply becomes
/* instruction branch 1 */
But in reality, it is probably more like this
{
/* instruction branch 1 */
}
But then the question becomes (going to back to the the very first example), how can I can I keep myObj
in scope outside the { ... }
?
First, your code won't work. if constexpr
really needs its condition to be dependent.
I'll fix it.
template<class MyClass>
void func() {
MyClass myObj = []{
if constexpr (std::is_default_constructible_v<MyClass>) {
return MyClass{};
} else {
return MyClass(10);
}
}();
myObj.func();
}
now
int main() {
func<MyClass>();
}
solves your problem.
Note that under c++17 rules, no copies or moves of MyClass
occur in the above code.