Что делать, если конфликтуют заголовки C++?

Очень странное дело. В коде применяется вектор и функция reverse (она нужна для реверса строки). И вот такое дело. Если у меня в коде так:

...
#include <vector>
using namespace std;
...

то компилятор выдаёт:

main.cpp: error: ‘reverse’ was not declared in this scope

reverse(mountstr.begin(), mountstr.end());

Эта часть кода "переворачивает" строку mountstr.

Но когда я делаю так:

...
#include <vector>
#include <algorithm>
using namespace std;
...

то выскакивают ошибки в векторах. Сразу приведу фрагменты кода (там огромный код), чтобы вы понимали, что к чему:

struct partition {
    unsigned int major;
    unsigned int minor;
    string blkdev;
    string name;
};
vector<partition> partinfo;
.....
partinfo.at(blks).major = stoi(uline);

А вот и ошибка:

main.cpp: error: template argument 1 is invalid
  145 |         vector<partition> partinfo;
      |                         ^
main.cpp:145:25: error: template argument 2 is invalid
main.cpp:161:34: error: request for member ‘at’ in ‘partinfo’, which is of non-class type ‘int’
  161 |                         partinfo.at(blks).major = stoi(uline);
      |                                  ^~

Да, вы не ослышались, тут натурально конфликт заголовков. Я даже пробовал убирать using namespace std; (говорят, не очень хорошая практика объявлять так std), дописал std:: куда надо - ровно эта же проблема никуда не делась.

Эх, если бы в C++ можно было подтянуть только одну функцию из импорта, как в python...


Ответы (2 шт):

Автор решения: Stanislav Volodarskiy

Вы можете использовать using namespace std; и никаких конфликтов не будет если соблюдать одно правило: не использовать имена определённые в стандартных заголовках включённых в файл. Например для кода ...

#include <vector>
#include <algorithm>
using namespace std;

... вам нужно избегать использования в коде следующих имён adjacent_find, all_of, any_of, begin, binary_search, clamp, common_comparison_category, compare_partial_order_fallback, compare_strong_order_fallback, compare_three_way, compare_three_way_result, compare_weak_order_fallback, copy, copy_backward, copy_if, copy_n, count, count_if, end, equal, equal_range, fill, fill_n, find, find_end, find_first_of, find_if, find_if_not, for_each, for_each_n, generate, generate_n, hash, includes, initializer_list, inplace_merge, is_eq, is_gt, is_gteq, is_heap, is_heap_until, is_lt, is_lteq, is_neq, is_partitioned, is_permutation, is_sorted, is_sorted_until, iter_swap, lexicographical_compare, lexicographical_compare_three_way, lower_bound, make_heap, max, max_element, merge, min, min_element, minmax, minmax_element, mismatch, move, move_backward, next_permutation, none_of, nth_element, partial_order, partial_ordering, partial_sort, partial_sort_copy, partition, partition_copy, partition_point, pop_heap, prev_permutation, push_heap, random_shuffle, ranges, remove, remove_copy, remove_copy_if, remove_if, replace, replace_copy, replace_copy_if, replace_if, reverse, reverse_copy, rotate, rotate_copy, sample, search, search_n, set_difference, set_intersection, set_symmetric_difference, set_union, shift_left, shift_right, shuffle, sort, sort_heap, stable_partition, stable_sort, strong_order, strong_ordering, swap, swap_ranges, three_way_comparable, three_way_comparable_with, transform, unique, unique_copy, upper_bound, vector, weak_order, weak_ordering и, возможно, некоторых других.

В вашем случае вы использовали имя partition а оно уже занято.

Лучше контролировать имена в глобальном пространстве используя их по одному:

#include <algorithm>
#include <vector>

using std::reverse, std::vector;

P.S. После using namespace std; вы не знаете какие имена заняты. Даже если вы думаете что знаете, другой компилятор задействует другие имена и ваш код радикально и не заметно для вас изменит смысл. Тоже произойдёт когда вы обновите версию C++. Особенно трудно с реализацией шаблонов. Не надо так делать. Не импортируйте пространства имён, импортируйте отдельные символы.

P.P.S. По просьбе KoVadim воспроизвожу ошибку:

#include <vector>
#include <algorithm>

using namespace std;

struct partition { };
struct test_t { vector<partition> partinfo; };
$ g++ -std=c++17 -pedantic -Wall -Wextra -Werror temp.cpp 
temp.cpp:9:33: error: template argument 1 is invalid
    9 | struct test_t { vector<partition> partinfo; };
      |                                 ^
temp.cpp:9:33: error: template argument 2 is invalid
→ Ссылка
Автор решения: RandomDice 779

Благодаря Stanisval Volodarsky я сделал так:

namespace emmc {
struct partition {
    unsigned int major;
    unsigned int minor;
    string blkdev;
    string name;
};
};

и

vector<emmc::partition> partinfo;
→ Ссылка