Does this code look fine

Ive been practicing with using iterators with vectors, vectors of pairs and maps, this happens to be a vector of pairs but it thought i would get it looked at since ive been using Chat GPT to help me a little, and I dont exactly trust it 100%. Ive been asking it to give me programming excercises in areas that I need to work on and std::map and iterators is one of them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>

auto Compare(const std::string& input, std::vector<std::pair<std::string, int>>& inventory)
{
	auto compareStrings = [&input](const std::pair<std::string, int>& a)
	{
		return a.first == input;
	};

	auto it = std::find_if(inventory.begin(), inventory.end(), compareStrings);

	return it;
}

int main()
{
	std::vector<std::pair<std::string, int>> inventory;

	inventory.push_back(std::make_pair("Stimpack", 9));
	inventory.push_back(std::make_pair("Pipboy", 1));
	inventory.push_back(std::make_pair("10mm Pistol", 1));
	inventory.push_back(std::make_pair("10mm Round", 34));

	for (auto& i : inventory)
	{
		std::cout << i.first << '(' << i.second << ")\n";
	}

	std::cout << "Use what item?\n";

	std::string input{ };
	std::cout << '>';
	std::getline(std::cin, input);

	auto itr = Compare(input, inventory);

	if (itr != inventory.end())
	{
		if (itr->first == "Pipboy")
		{
			std::cout << "You cannot drop " << input << " are you crazy?! Make a sensible choice this time!\n";
		}
		else if (itr->first == "10mm Pistol")
		{
			std::cout << "Shot 15 10mm rounds!\n";

			auto find10mm = Compare("10mm Round", inventory);
			if (find10mm != inventory.end() && find10mm->second >= 15)
			{
				find10mm->second -= 15;
			}
		}
		else if (itr->first == "10mm Round")
		{
			std::cout << "This item can only be used in the 10mm Pistol!\n";
		}
		else
		{
			std::cout << input << " used\n";
			if (itr->second > 0)
			{
				itr->second--;
			}
		}
	}
	else
	{
		std::cout << input << " does not exist\n";
	}

	std::cout << '\n';

	for (auto& i : inventory)
	{
		std::cout << i.first << '(' << i.second << ")\n";
	}

	return 0;
}
Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>

using Data = std::pair<std::string, int>;
using DB = std::vector < Data>;

auto Compare(const std::string& input, DB& inventory) {
	const auto compareStrings = [&input](const Data& a) {
		return a.first == input;
	};

	return std::find_if(inventory.begin(), inventory.end(), compareStrings);
}

int main() {
	DB inventory;

	const auto display = [&inventory] {
		for (const auto& [name, qty] : inventory)
			std::cout << name << " (" << qty << ")\n";
	};

	inventory.emplace_back("Stimpack", 9);
	inventory.emplace_back("Pipboy", 1);
	inventory.emplace_back("10mm Pistol", 1);
	inventory.emplace_back("10mm Round", 34);

	display();

	std::string input;

	std::cout << "Use what item?\n>";
	std::getline(std::cin, input);

	if (const auto itr = Compare(input, inventory); itr != inventory.end())
		if (itr->first == "Pipboy")
			std::cout << "You cannot drop " << input << " are you crazy?! Make a sensible choice this time!\n";
		else if (itr->first == "10mm Pistol") {
			std::cout << "Shot 15 10mm rounds!\n";

			if (const auto find10mm = Compare("10mm Round", inventory); find10mm != inventory.end() && find10mm->second >= 15)
				find10mm->second -= 15;

		} else
			if (itr->first == "10mm Round")
				std::cout << "This item can only be used in the 10mm Pistol!\n";
			else {
				std::cout << input << " used\n";

				if (itr->second > 0)
					--itr->second;
			}
	else
		std::cout << input << " does not exist\n";

	std::cout << '\n';
	display();
}

Last edited on
Lines 24-27 create a lot of temporaries using make:pair and push_back. Using emplace_back does the element construction in place, as seeplus shows.
Compare offers a potential use-case for range projections. Could be:
1
2
3
4
5
6
7
8
9
// Used to be named "Compare"
[[nodiscard]]
auto Find(
  std::string_view name,
  std::vector<std::pair<std::string, int>>& inventory)
{
    return std::ranges::find(inventory, name, 
      [](auto pair) -> std::string_view { return pair.first; });   
}


Or
1
2
3
4
5
6
7
[[nodiscard]]
auto Find(
  std::string_view name,
  std::vector<std::pair<std::string, int>>& inventory)
{
    return std::ranges::find(inventory, name, &std::pair<std::string, int>::first);   
}


About #2, I believe it is okay to address standard library member data despite the restrictions on addressing standard library functions and member functions. If in doubt, use a lambda.
Last edited on
Topic archived. No new replies allowed.