#c #vector #stl #folly
#c #вектор #stl #глупость
Вопрос:
Я создал простую программу на C для чтения и маркирования входных данных из cin. Однако, хотя токены в моей вспомогательной функции верны, токены в вызывающей функции (main) являются мусорными значениями.
Например, если я ввожу «a b c» в качестве входных данных, вектор токенов в моей вспомогательной функции (get_input_tokens) содержит «a», «b», «c», но вектор токенов в main содержит «?», «?», «».
Я понимаю, что вектор должен быть возвращен по значению вызывающему объекту, поэтому в вызывающем объекте (main) должна быть создана новая копия вектора, идентичная исходному вектору. Кто-нибудь сможет дать мне несколько идей о том, почему это происходит?
#include <folly/String.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<folly::StringPiece> get_input_tokens() {
string input;
getline(cin, input); // Enter in "a b c"
vector<folly::StringPiece> tokensVec;
folly::split(" ", input, tokensVec);
// Print tokensVec - prints out "a", "b", "c"
for (int i=0; i<tokensVec.size(); i ) {
cout << tokensVec[i] << endl;
}
return tokensVec;
}
int main(int argc, char *argv[]) {
auto tokensVec = get_input_tokens();
// Print tokensVec - prints out "?", "?", ""
for (int i=0; i<tokensVec.size(); i ) {
cout << tokensVec[i] << endl;
}
return 0;
}
Ссылка на folly::split:https://github.com/facebook/folly/blob/master/folly/String.h#L403 .
Комментарии:
1. Что такое
folly::split
? Кажется, это наиболее подходящая функция для создания вектора. Пожалуйста, добавьте это в свой вопрос.2. Можете ли вы поделиться с нами реализацией folly / String? Насколько мне известно, компиляторы решают, как его вернуть, и для выполнения этой задачи можно использовать конструктор перемещения или конструктор копирования. Таким образом, проблема, вероятно, либо в конструкторе копирования, либо в конструкторе перемещения класса folly / String.
3. Спасибо за быстрый ответ! Ах, извините, забыл добавить это — это библиотечная функция из folly (Facebook библиотека C с открытым исходным кодом), которая выполняет то же самое, что и функция разделения Python (т. Е. разбивает входную строку на разделитель). Ссылка: github.com/facebook/folly/blob/master/folly/String.h#L403 .
4. Спасибо за быстрый ответ! Конечно, вот реализация: github.com/facebook/folly/blob/master/folly/String.h#L403 . Я вижу, это имеет смысл — в таком случае позвольте мне взглянуть на конструкторы перемещения и копирования для folly::StringPiece.
Ответ №1:
Это потому, что a StringPiece
содержит указатели на строку, частью которой он является.
В вашем случае это input
, который уничтожается при возврате функции и делает все StringPiece
значения недействительными.
Вам нужен другой тип для токенов.
Я не знаком с folly, но если создатели не потеряли сюжет полностью, std::string
должно сработать.
Комментарии:
1. Спасибо за объяснение! Я не знал, что StringPiece содержит указатели на другую строку — имеет смысл, что если он указывает на локальную переменную, то это было бы недопустимо вне области видимости этой переменной. Я пытался с помощью std:: string, но получаю эти ошибки: ` Неопределенные символы для архитектуры x86_64: «folly::makeConversionError (folly::ConversionCode, folly::Range<char const*>)», на которые ссылается: std::__1::enable_if<!(std::is_same<folly::Range<char const*>, std:: __1::basic_string` Но я создам новый вопрос для этого, поскольку это другая проблема.