Если вы не хотите использовать указатели для получения справочной функциональности, как объяснил Игорь (и другие) в первом комментарии к вашему вопросу, тогда вы можете сделать пару вещей.
Во-первых, философия типов значений вместо ссылочных типов заключается в , не создавайте их, пока они вам не понадобятся . Ваш соблазн объявить ссылку перед использованием объекта для получения своего рода полиморфной функциональности в оставшейся части функции (возможно, некоторый общий код инициализации после создания) является разумным замыслом, но его нельзя выразить так, как вы его написали, потому что он будет включать создание стоимости.
Вы могли бы предоставить конструктор по умолчанию и дать ему некоторое поведение - но совершенно очевидно, что ни вы, ни кто-либо другой не хотят, чтобы вас принуждали к этому.
Суть альтернативы заключается в том, чтобы переместить переменную в область видимости и вернуть ее.
Foo makeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Очевидно, что это препятствует написанию общего кода инициализации после создания после блока if перед return . Чтобы сделать это, вы должны написать блок if в своей собственной функции и вернуть результат, а затем написать следующий код после инициализации объекта.
Foo premakeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Foo makeFoo(int x) {
Foo result = premakeFoo(x);
// common post init code can go here.
return result;
}
Если вы не хотите, чтобы это было совершенно отдельной функцией, вы можете сделать лямбду.
Foo makeFoo(int x) {
Foo result = ([=]() {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
})();
// common post init code can go here.
return result;
}
Или в вашем случае, если оно маленькое, используйте встроенное троичное выражение.
Foo makeFoo(int x) {
Foo result = (x > 10) ? Foo(true) : Foo(false); // or just Foo(x>10)
// common post init code can go here.
return result;
}
Существуют и другие хитрые варианты, включающие шаблоны, но все они вращаются вокруг идеи выделения различных выражений для перегруженных конструкторов, а затем использования присваивания для инициализации переменной с использованием более сложного выражения. И то, что вы пытаетесь сделать, это получить выражение, которое создает значение двумя различными способами, чтобы охватывало область видимости (охватывало , если блоки). Тройки и функции - это варианты получения логики if , выполняемой в одном выражении.