2016-05-05 6 views
-3

Я наблюдал CppCon «Запись Хорошо C++ 14 ... По умолчанию» Херб Саттер и на одном из слайдов был следующий фрагмент кода:Когда цикл «для каждого» возвращает nullptr для элемента?

auto p = make_shared<circle>(42); 
auto v = load_shapes(); 
for(auto& s: v) { 
    if(s && *s == *p) { 
    cout << *s << "is a match\n"; 
    } 
} 

Мой вопрос: почему существует

если (s & & * s == * р)

чек?

Как можно ссылаться на переменную, инициализированную для каждого loop be nullptr? Loop выполняет итерацию по элементам, поэтому в этом случае может быть назначено значение nullptr?

EDIT: Моя точка интереса, что эта проверка:

if(s) 

Когда s получается «для каждого», как это может быть пустым?

+0

Рассмотрите тип 'v' может быть' std :: vector '. – GManNickG

+1

Это не имеет никакого отношения к ссылкам. Когда вы используете ссылку, вы просто используете переменную, к которой она привязана, вы не используете «ссылочную переменную». Таким образом, в этом коде объекты в 'v' могут быть преобразованы в bool. Тот факт, что код использует ссылку, не имеет значения. –

+1

'using namespace std;' не хороший код - это подразумевается в этом примере –

ответ

3

Предположим следующие определения.

struct circle { 
    circle(int r) :radius(r) {} 
    int radius; 

    bool operator==(circle rhs) const { 
     return radius == rhs.radius; 
    } 
}; 

std::vector<circle*> load_shapes() { 
    std::vector<circle*> vec; 
    for (int i = 0; i < 10; ++i) 
     vec.push_back(nullptr); 
    return vec; 
} 

При том, что теперь можно вставить пример кода в основную функцию:

int main() { 
    using namespace std; 
    auto p = make_shared<circle>(42); 
    auto v = load_shapes(); 
    for(auto& s: v) { 
     if(s && *s == *p) { 
     cout << *s << "is a match\n"; 
     } 
    } 
} 

С этим определением для load_shapes, v (в основном) имеет типа std::vector<circle*>, он имеет 10 элементов, все они имеют нулевые указатели. Поэтому в цикле for s имеет тип circle*& (ссылка на указатель на круг). И в каждой итерации указатель, на который он ссылается, является нулевым указателем. Это то, что проверяет инструкция if.

Обратите внимание, что есть, конечно, другие возможные определения. Например, load_shapes может вернуть std::vector<std::shared_ptr<shape>>, где shape является базовым классом circle (и я подозреваю, что это именно то, что имел в виду автор слайдов).

Смежные вопросы