Я хочу иметь возможность обнаруживать последнюю итерацию в моем итераторе карты. Как бы я этого добился?
class JSON {
public:
static void stringify(map<string, string> data)
{
string base;
base += "{ ";
for (map<string, string>::iterator it = data.begin(); it != data.end(); ++it)
{
cout << it->first.c_str() << " => " << it->second.c_str() << endl;
}
}
};
Я попробовал это, и он выдал эту ошибку: Severity Code Description Project File Line Suppression State Error C2679 binary '<<': no operator found which takes a right-hand operand of type '_Ty1' (or there is no acceptable conversion)
Чему ваш компилятор говорит, что _Ty1 равно? Предполагая, что вы используете Visual Studio, это должно быть в следующей строке вывода. У вас есть #included string и iostream? Кроме того, какую версию Visual Studio вы используете?
Я включаю <iostream>, но не включаю <string>. Я использую VS 2017 версии 15.9.11.
Ну, вы должны #include <string>, прежде чем использовать std::string.





Этого можно достичь, создав индекс, увеличивая индекс на каждой итерации вашей карты, а затем для каждой итерации сравнивая размер вашей карты с индексом.
class JSON {
public:
static void stringify(map<string, string> data)
{
string base;
int index = 0;
base += "{ ";
for (map<string, string>::iterator it = data.begin(); it != data.end(); ++it)
{
if (data.size() - 1 == index)
{
// Do stuff here
}
cout << it->first.c_str() << " => " << it->second.c_str() << endl;
index++;
}
}
};
Вы можете просто переместить проверку границ итератора в тело цикла:
void stringify(map<string, string> data){
string base;
base += "{ ";
for (map<string, string>::iterator it = data.begin();;){
if (it == data.end()){
cout << "Last iteration!";
break;
}
cout << it->first << " => " << it->second << endl;
++it;
}
}
Обратите внимание, что код в операторе if будет вызываться для пустой карты.
Вы можете использовать станд:: пред. следующим образом:
for(auto it = data.begin(); it != data.end(); ++it)
{
if (it == std::prev(data.end()))
{
// this is the last iteration
}
std::cout << it->first << " => " << it->second << '\n';
}
станд:: пред. возвращает итератор предыдущий из своего параметра.
Внутри каждой итерации цикла вы можете проверить, соответствует ли итератор следующий итератору карты end() или нет, например:
static void stringify(map<string, string> data)
{
string base;
base += "{ ";
auto it = data.begin();
auto end = data.end();
while (it != end)
{
auto next_it = std::next(it);
if (next_it == end) {
cout << "this is the last iteration!" << endl;
}
cout << it->first << " => " << it->second << endl;
it = next_it;
}
}
Или:
static void stringify(map<string, string> data)
{
string base;
base += "{ ";
auto it = data.begin();
auto end = data.end();
if (it != end)
{
do
{
cout << it->first << " => " << it->second << endl;
auto next_it = std::next(it);
if (next_it == end) {
cout << "that was the last iteration!" << endl;
break;
}
it = next_it;
}
while (true);
}
}
Если ваша цель состоит в том, чтобы просто избежать вставки запятой в ваш вывод JSON на первой или последней итерации (в зависимости от того, где в вашем коде вы хотите сделать эту вставку), вы можете сделать это следующим образом:
static void stringify(map<string, string> data)
{
string base = "{";
auto it = data.begin();
auto end = data.end();
if (it != end)
{
cout << it->first << " => " << it->second << endl;
base += (" \"" + it->first + "\": \"" + it->second + "\"");
while (++it != end)
{
cout << it->first << " => " << it->second << endl;
base += (", \"" + it->first + "\": \"" + it->second + "\"");
}
}
base += " }";
}
Примечание:
cout << it->first.c_str()можно заменить наcout << it->first