声明变量而不进行初始化的最佳实践,因此auto不可用

时间:2015-02-11 10:06:48

标签: c++ c++11

我想声明两个相同类型的变量,并让编译器找出类型。但是我不想在以后初始化其中一个变量。我不认为我可以在这里使用auto,那么最佳选择是什么?

std::vector<int> v;

// `start` and `end` should be the same type
auto start = v.begin();
??? end;

// complicated code to assign a value to `end` (i.e. putting
// the code in a function or using ?: is not practical here)  
if (...) {
    end = ...;
} else {
    end = v.end();
}

告诉编译器end应该与start的类型相同,但不必初始化变量的最佳方法是什么?

auto start = v.begin(), end;  // Doesn't work, `end` has to be initialised
decltype(start) end;          // Does work, but not sure if it's best practice

更新

有几条评论提出了在某些情况下可行的方法,所以我在这里澄清我的情况:

std::vector<int> v;
int amount = 123;

// `start` and `end` should be the same type
auto start = v.begin();
??? end;

// code to assign a value to `end`
if (amount) {
    end = start + amount;
    amount = 0;
} else {
    end = v.end();
}

我相信lambda函数在这里会比较棘手,因为amount在计算0后被重置为end,因此在lambda函数中计算{{1}的值}},end必须在amount = 0语句之后。唯一的选择是创建更多的局部变量,这会导致(通常很小的)性能损失。

5 个答案:

答案 0 :(得分:10)

我个人的做法是就地召唤lambda:

std::vector<int> v;

///////////////////

auto start = v.begin(), end = [&]{
    if (...) {
        // complicated code to compute a value for `end`
    }
    else
        return v.end();
}();

如果lambda的自动返回类型推断因任何原因失败(例如,有多个return语句),则只需将[&]{替换为[&]() -> decltype(start) {


修改

std::vector<int> v;
int amount = 123;

///////////////////

auto start = v.begin(), end = [&]{
    auto ret = v.end();
    if (amount) {
        ret = start + amount;
        amount = 0;
    }
    return ret;
}();

答案 1 :(得分:9)

我认为这里未初始化的变量是过早优化。我会初始化变量,只考虑我是否有证据证明它会产生影响。

auto start = v.begin();
auto end = v.end();

if (amount) {
    end = start + amount;
    amount = 0;
}

答案 2 :(得分:6)

这是一个使用好的旧三元运算符的例子(@ 5gon12eder也提到过)。在这样一个简单的情况下,这是最好的可理解的恕我直言,也避免了未初始化变量的问题,由@ildjarn指出。

auto start = v.begin();
auto end = amount
    ? start + amount
    : v.end();
amount = 0;

答案 3 :(得分:5)

auto start = v.begin();
decltype(start) end; // Must have a default constructor though.

答案 4 :(得分:5)

这不是过度解决问题吗?要么是你的第一个直觉:

auto start = v.begin();
decltype(start) end;

auto - 使用end初始化v.end()变量,并在演示代码中删除else子句。它很简单:

auto start = v.begin();
auto end = v.end(); // Or v.begin() depending on your preference, the whole container or nothing by default

// code to assign a value to `end` IF it must be different from v.end()
if (amount) {
    end = start + amount;
    amount = 0;
}

与维护/可读性成本相比,初始化或分配迭代器的成本无论如何都应该可以忽略不计。