另一个函数中的std :: vector初始化

时间:2018-03-11 12:52:29

标签: c++ vector initialization try-catch

我需要初始化向量并检查初始化是否已成功多次,所以我决定为此创建一个函数。问题是我还没有找到解决这个问题的方法而不会失去很大的效率。到目前为止,这是我的尝试:

    #include <iostream>
    #include <vector>

    bool init(std::vector<double>& v, int n, double x) {
        try {
            v = std::vector<double>(n, x);
        }
        catch (std::bad_alloc& e) {
            std::cerr << "Error: " << e.what() << std::endl;
            return false;
        }        

        return true;
    }

    int main() {
        int n = -1;
        std::vector<double> v;

        if (not init(v, n, 1)) {
            std::cerr << "Vector failed to initialize" << std::endl;
        }
        else {
            for (int i = 0; i < n; ++i) {
                std::cout << v[i] << std::endl;
            }
        }
    }

请注意,我创建了一个新的向量,然后调用了复制构造函数,因此成本类似于初始化两个向量而不是一个向量。有没有一种有效的替代方案?

2 个答案:

答案 0 :(得分:2)

  

请注意,我创建了一个新的向量,然后调用了复制构造函数,因此成本类似于初始化两个向量而不是一个向量。

我不这么认为。

您创建一个空的std::vector<double> v,这是一个相对便宜的操作,然后在init()内为其分配一个新值。

但是,在init()中,临时std::vector<double>(n, x)被分配给v,因此将调用移动赋值运算符,而不是复制构造函数,并且不会执行不必​​要的复制。

答案 1 :(得分:2)

构建后,您无法初始化。但是,对“问题”最简单的“解决方案”是在适当的位置构造向量,而不是使用带有“输出参数”的“init”函数。

int main() {
    int n = -1;
    try
    {
        std::vector<double> v(n, 1);
        for (int i = 0; i < n; ++i) {
            std::cout << v[i] << std::endl;
        }
    }
    catch(const std::bad_alloc&)
    {
        std::cerr << "Vector failed to initialize" << std::endl;
    }
}

如果您确实需要向量的“init”函数,则按值返回并使用它在调用者端初始化某些内容。

std::vector<double> init(int n, double x) {
  return std::vector<double>(n, x);
}

这两个版本都会让您少考虑一些事情。例如,您不必首先实例化和清空向量,然后检查函数的返回值(您可以轻易忽略它),并且您不必记录如果传递非空向量会发生什么,如果您是该功能的用户,请阅读文档。