C ++ - `алгоритм`, библиотека и пространство имен` std` - PullRequest
1 голос
/ 02 февраля 2020

Я понял, что можно использовать множество (возможно, все) функций библиотеки algorithm с или без пространства имен std: например, когда импортируется algorithm:

#include <algorithm>

std::unique и unique кажутся эквивалентными. Вот пример:

#include <iostream>
#include <vector>
#include <algorithm>


int main () {
    std::vector<int> v = {10,20,20,20,30,30,20,20,10};
    std::vector<int>::iterator it;

    it = std::unique (v.begin(), v.end());
    for (it=v.begin(); it!=v.end(); ++it)
        std::cout << ' ' << *it;
        std::cout << '\n';

    it = unique (v.begin(), v.end());
    for (it=v.begin(); it!=v.end(); ++it)
        std::cout << ' ' << *it;
        std::cout << '\n';
}

Вывод:

10 20 30 20 10 30 20 20 10
10 20 30 20 10 30 20 20 10

1) Это те же функции?

2) Какой механизм позволяет использовать эти функции независимо от использования пространства имен std? Я посмотрел исходный код: https://github.com/gcc-mirror/gcc/blob/d9375e490072d1aae73a93949aa158fcd2a27018/libstdc%2B%2B-v3/include/bits/stl_algo.h

и

https://github.com/gcc-mirror/gcc/blob/d9375e490072d1aae73a93949aa158fcd2a27018/libstdc%2B%2B-v3/include/std/algorithm

, но я до сих пор понятия не имею о том, как это работает.

Заранее спасибо.

1 Ответ

4 голосов
/ 02 февраля 2020

Как уже упоминалось в комментариях, unique без std:: работает из-за аргумент-зависимого поиска.

v.begin() и v.end() return std::vector<int>::iterator, что является некоторым итератором для std::vector<int>. Это может быть любой тип, удовлетворяющий требованиям итератора. Это может быть простой указатель на int или, что более вероятно, на класс с перегруженными операторами.

Если итератор является типом класса, тогда поиск по аргументу будет искать unique в этом классе и в классах, включающих его. область имен Если в этом объеме области имен входит ::std, то будет найден и использован ::std::unique.

Нет гарантии, что это работает. Это зависит от реализации стандартной библиотеки, будет ли это или нет.

Например, с std::array вместо std::vector он работает на MSV C, но не на Clang (с libc ++) или G CC (с libstdc ++), поскольку последние два просто используют int* в качестве итератора, см. https://godbolt.org/z/Ysu2-d.

Вы всегда должны ссылаться на std::unique с его полным именем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...