Я пытался поместить каждый элемент вектора целых чисел в строку. Я хочу добиться этого путем преобразования целых чисел в строки, после чего я объединяю эти «маленькие строки» в одну большую строку, которая будет представлять все элементы этого конкретного вектора.
Это может выглядеть глупо, но действительно полезно, если вы хотите создать функцию, которая возвращает вектор, подобный чему-то, и т. д.
Единственная проблема в том, что я получаю сообщение об ошибке в строке 13, в которой говорится:
error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(int&)’
13 | myString += (string) myVector[i];
| ^
и я не имею ни малейшего представления о том, почему это происходит. Мой код следует ниже:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int myVector[5] = {1,2,3,4,5};
string myString = "";
for (int i =0; i < 5; i++)
{
myString += (string) myVector[i];
myString += "\n";
}
cout << myString << endl;
Любая помощь будет высоко ценится.
И в качестве общего совета: всякий раз, когда вы чувствуете необходимость выполнить приведение в стиле C (например, при попытке преобразовать целое число в строку), вы должны рассматривать это как признак того, что вы делаете что-то неправильно.
и я не имею ни малейшего представления о том, почему это происходит. Возможно, вы привыкли к другим языкам, которые выполняют такой тип преобразования целого числа в строку, где все, что вам нужно сделать, это иметь +
и волшебным образом целое превратится в строку? Если да, то вы видите, что C++ так не работает.
в общем, найти все возможные преобразования непросто, найти отсутствие преобразования еще сложнее, но неплохо начать с конструкторов std::string
en.cppreference.com/w/cpp/string/basic_string/basic_string
Вы можете использовать std::to_string для преобразования int
в std::string
.
Измените эту строку:
myString += (string) myVector[i];
К:
myString += std::to_string(myVector[i]);
Примечание: подобное объединение строк может быть не столь эффективным из-за создания и уничтожения временных строк (хотя вполне вероятно, что сработает оптимизация небольших строк, поэтому дополнительных выделений кучи не будет).
Как прокомментировал @Someprogrammerdude, вы можете использовать std::ostringstream
.
Боковые примечания:
#include <string>
.создается и уничтожается много временных строк. Из-за SSO вряд ли произойдет выделение кучи.
@Evg разъяснил этот момент.
Вы можете использовать std::stringstream
#include <iostream>
#include <string>
#include <sstream>
int main()
{
int myVector[5] = {1,2,3,4,5};
std::string myString;
std::stringstream sstream;
for (auto i : myVector)
sstream << i;
sstream >> myString;
std::cout << myString;
}
Перегрузите оператор потока вывода, и тогда у вас будет что-то, что можно использовать повторно во многих сценариях.
Основываясь на приведенных ниже отзывах, перегрузка - не лучший ответ, другой подход здесь: https://www.onlinegdb.com/zDUjVbSTp
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
// Overloading operator<< will have many benefits.
// you can use it to output an array to std::cout directly
// or you can write it to a file or stringstream
std::ostream& operator<<(std::ostream& os, const std::vector<int>& values)
{
os << "[";
bool comma = false;
for (const auto& value : values)
{
if (comma) os << ", ";
os << value;
comma = true;
}
os << "]";
return os;
}
int main()
{
std::vector<int> values{ 1,2,3,4,5 };
// write directly to std::cout
std::cout << "direct : " << values << "\n";
// adding array to a string
std::ostringstream os;
std::string string{ "output = " };
os << values;
string += os.str();
std::cout << string << "\n";
return 0;
}
Я бы не стал перегружать операторы для стандартных типов. Предположим, вы используете библиотеку, которая также предоставляет такую перегрузку, и другую, которая делает то же самое...
Это справедливое замечание
Перегрузка operator<<
имеет смысл для типов, для которых у вас есть более или менее канонический формат вывода, например целые числа или строки. Для таких типов, как std::vector<T>
, это сомнительно, потому что не существует канонического вывода — можно использовать пробелы или запятые в качестве разделителей, помещать или не заключать всю последовательность в скобки и т. д.
между прочим, именованная функция void print(std::ostream& out,const std::vector<int>&)
имеет те же преимущества, которые вы перечисляете.
@463035818_is_not_a_number Да я и сейчас это понимаю :) onlinegdb.com/zDUjVbSTp
Я оставлю этот ответ как есть, так как я думаю, что он содержит полезную информацию и для других :)
Вы можете использовать библиотеку fmt
:
fmt::join
примет диапазон, в вашем случае вектор целых чисел, и соединит его содержимое с заданным разделителем (например, пустую строку, если вы просто хотите, чтобы все элементы были вместе).fmt::format
создаст строку с заданным форматом, в данном случае только содержимое объединенного вектора.#include <fmt/ranges.h>
int main() {
int myVector[5] = {1,2,3,4,5};
auto myString = fmt::format("{}", fmt::join(myVector, ""));
fmt::print("{}\n", myString);
}
// Outputs: 12345
Или, проще, если вам не нужна строка:
int main() {
int myVector[5] = {1,2,3,4,5};
fmt::print("{}\n", fmt::join(myVector, ""));
}
Ошибка, которую вы получаете, говорит о том, что компилятор не может найти функцию std::__cxx11::basic_string<char>::basic_string(int&)
, то есть конструктор std::string
, принимающий int&
.
Я добавлю свое собственное решение, как указано в моем комментарии:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
int main()
{
std::vector myvector = { 1, 2, 3, 4, 5 };
std::copy(std::begin(myvector), std::end(myvector),
std::ostream_iterator<int>(std::cout, "\n"));
}
Вы также можете использовать алгоритм for_each для конкатенации.
#include <iostream>
#include <algorithm>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6};
std::string all;
std::for_each(v.begin(), v.end(), [&, del = ""](const int &e) {
all += std::to_string(e) + (&e == &v.back() ? "" : del);
});
std::cout << all << std::endl;
}
выход:
123456
Если вы хотите добавить разделитель между ними, просто измените значение del
в лямбда-захвате.
std::for_each(v.begin(), v.end(), [&, del = "-"](const int &e) {
all += std::to_string(e) + (&e == &v.back() ? "" : del);
});
Выход:
1-2-3-4-5-6
std::cout
напрямую.