Что делать, если конфликтуют заголовки 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 шт):
Вы можете использовать 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
Благодаря Stanisval Volodarsky я сделал так:
namespace emmc {
struct partition {
unsigned int major;
unsigned int minor;
string blkdev;
string name;
};
};
и
vector<emmc::partition> partinfo;