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

Mal*_*ous 8 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();
}
Run Code Online (Sandbox Code Playgroud)

什么是告诉编译器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
Run Code Online (Sandbox Code Playgroud)

更新

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

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();
}
Run Code Online (Sandbox Code Playgroud)

我相信lambda函数在这里会比较复杂,因为amount正在重置为0after end,所以在计算值的lambda函数中end,amount = 0必须在return语句之后.唯一的选择是创建更多的局部变量,这会导致(通常很小的)性能损失.

ild*_*arn 10

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

std::vector<int> v;

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

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

如果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;
}();
Run Code Online (Sandbox Code Playgroud)


Chr*_*rew 9

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

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

if (amount) {
    end = start + amount;
    amount = 0;
}
Run Code Online (Sandbox Code Playgroud)


win*_*tou 6

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

auto start = v.begin();
auto end = amount
    ? start + amount
    : v.end();
amount = 0;
Run Code Online (Sandbox Code Playgroud)


Max*_*kin 5

auto start = v.begin();
decltype(start) end; // Must have a default constructor though.
Run Code Online (Sandbox Code Playgroud)

  • 这基本上不是来自OP的复制和粘贴吗?我很感激,如果你可以添加一些解释,为什么你认为这是一个比OP(显然已经意识到它)更好的解决方案. (4认同)

Hir*_*aCC 5

它不是在过度思考这个问题吗?要么是你的第一直觉:

auto start = v.begin();
decltype(start) end;
Run Code Online (Sandbox Code Playgroud)

或者 - 使用的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;
}
Run Code Online (Sandbox Code Playgroud)

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