声明变量,其类型具有已删除的默认构造函数,但没有值

问题描述 投票:-1回答:1

我想在多个if-else分支中初始化一个变量,稍后使用,基本上是这样的:

Foo foo;

if (someCondition) {
    std::string someString = getTheString();
    // do some stuff
    foo = Foo(someString);
} else {
    int someInt = getTheInt();
    //do some other stuff maybe
    foo = Foo(someInt);
}

// use foo here

不幸的是,在此示例中,类型Foo的默认构造函数已删除,因此上面的代码无法编译。有没有办法以这种方式初始化这样的变量?

编辑:

您可以在示例中看到,我正在使用不同的构造函数,并且还在if / else块中执行其他操作,因此很遗憾,三元运算符不起作用。如果没有办法,没有foo作为指针,我显然可以采用另一种方法,但是我很好奇,如果我的方法可以工作。

c++ default-constructor variable-declaration
1个回答
5
投票

您还没有告诉我们为什么您不能使用指针...但是,与此同时,这是一个表面上没有指针的解决方案:

#include <optional>    
std::optional<Foo> foo;

if (someCondition) {
    std::string someString = getTheString();
    // do some stuff
    foo.emplace(someString);
} else {
    int someInt = getTheInt();
    //do some other stuff maybe
    foo.emplace(someInt);
}
if (foo.has_value()) { /* use foo here */ }

如果您有编码标准或某些禁止使用raw指针(和new的指针,则可以使用std::unique_ptr

#include <memory>
std::unique_ptr<Foo> foo;

if (someCondition) {
    std::string someString = getTheString();
    // do some stuff
    foo = std::make_unique<Foo>(someString);
} else {
    int someInt = getTheInt();
    //do some other stuff maybe
    foo = std::make_unique<Foo>(someInt);
}
if (foo) {/* use foo here */}

您还可以将Foo创建逻辑放在单独的函数(或lambda)中:

auto getFoo(/* ... */) {
    if (someCondition) {
        std::string someString = getTheString();
        // do some stuff
        return Foo(someString);
    } else {
        int someInt = getTheInt();
        //do some other stuff maybe
        return Foo(someInt);
   }
}
// ...
Foo foo = getFoo(/*...*/);
// use foo here

-1
投票

如果对象不是复制/可移动构造的,并且您要避免动态分配,则可以使用variant进行就地分配(这等效于使用new和delete放置,但是您不能忘记删除):

std::variant<std::monostate, Foo> vfoo;

if (true) {
    std::string someString = "abc";
    // do some stuff
    vfoo.emplace<Foo>(someString);
} else {
    int someInt = 3;        //do some other stuff maybe
    vfoo.emplace<Foo>(someInt);
}

// handy name to avoid needing to type `get` every time you want the object
Foo& foo = get<1>(vfoo);
© www.soinside.com 2019 - 2024. All rights reserved.