Неэффективны ли сравнения между итератором и const_iterator?

Вариант a:

const auto end = whatever.end();
for (auto it = whatever.begin(); it != end; ++it)
{
    // ...
}

Вариант b:

const auto end = whatever.cend(); // note the call to cend insteand of end here
for (auto it = whatever.begin(); it != end; ++it)
{
    // ...
}

Есть ли основания полагать, что вариант b будет менее эффективным, чем вариант a, поскольку условие цикла сравнивает два разных итератора? Означает ли это неявное преобразование на it?

(end используется несколько раз внутри цикла for, следовательно, мое желание вытащить его.)

Ответ 1

В принципе, он может быть менее эффективным и приводить к неявному преобразованию с ненулевой стоимостью.

На практике iterator и const_iterator могут участвовать в соотношении наследования (либо один происходит от другого, либо оба происходят из _iterator_base), так что оператор неравенства определяется в базовом классе и нет необходимости в неявном преобразовании (вместо этого игнорируется более производительный итератор). Даже в отсутствие этих преобразований, вероятно, будет достаточно тривиально, чтобы быть встроенным и оптимизированным.

libstdС++ оптимизирует эти сравнения по-разному, определяя operator== и operator!= между iterator и const_iterator: http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a02037.html#l00295

libС++ не имеет никакой оптимизации: http://llvm.org/svn/llvm-project/libcxx/trunk/include/__tree - хотя конструктор const_iterator из iterator является настолько тривиальным, что Я ожидаю, что он будет полностью оптимизирован.