提问者:小点点

如何在try块中实例化变量?


最好的方法是什么:

for (const auto &arg : args) {
    try {
        auto var = create(arg);
    } catch (const std::invalid_argument &e) {
        continue;
    }
    // ...
    // use(var)
    // ...
}

一种方法是移动

    // ...
    // use(var)
    // ...

进入try块,但这会引入整个嵌套负载。 另外,我不想从use中捕获错误

TypeOf(var)是一个没有默认构造函数的类。


共3个答案

匿名用户

一种方法是将use(var)移到try块中,但这会引入大量嵌套

您可以将use(var)移到单独的函数中,并在try块中调用该函数:

void use(var_type& var) {
    //...
}
for (const auto &arg : args) {
    try {            
        auto var = create(arg);
        use(var);
    } catch (const std::invalid_argument &e) {
        continue;
    }
}

由于您无法控制createuse块,并且希望确保不捕获在use块中抛出的任何内容,因此可以将create异常作为不同类型重新抛出,以仅捕获该异常。 由于异常应该只发生在异常情况下,因此这种开销应该不是任何问题。

示例:

struct create_error : std::invalid_argument {
    using std::invalid_argument::invalid_argument;
};

Foo create(const char* arg) {
    return {arg};
}

Foo create_wrapper(const char* arg) {
    try {
        create(arg);
    }
    catch(const std::invalid_argument& ex) {
        throw create_error(static_cast<const create_error&>(ex));
    }
}

void use(Foo& f) {
    // may throw std::invalid_argument, but it won't be caught below
}
for (const auto& arg : args)
{        
    try {
        auto var = create_wrapper(arg);
        use(var);
    }
    catch (const create_error& e) {
        continue;
    }        
}

匿名用户

也许std::optional才是您需要的。 您可以将它与没有默认构造函数的类一起使用,如下所示

如果您不想知道抛出异常的值是什么,可以使用如下所示的方法

#include <iostream>
#include <optional>

struct A{
    int var;
    explicit A(int arg):var{arg}{}
    A() = delete ;
};
A create( int arg){
    if (arg == 5 || arg == 8)
        throw std::invalid_argument{""};
    return A{arg};
}

void use(const A & a)
{
    std::cout << "\n" << a.var;
}
int main()
{
    std::optional<A> a;
    for (size_t i{}; i < 10; ++i) {
        try {
            a = create(i);
        } catch (const std::invalid_argument &e) {
                continue;
        }
        if(a) use(a.value());

    }

}

活着

匿名用户

我认为它主要取决于变量类型。

例如,如果它是一个指针(smart或dumb),您可以将它设置为try块之前的nullptr,并检查它是否被分配在try块之外。

如果它是另一种类型,无法获取nullptr,则可以使用默认值(如果可能的话)。 如果这是不可能的,那么,你应该给出一个具体的例子,也许你可以得到一个更好的答案。