Мне нужна была простая в использовании библиотека C ++ для разбора CSV-файлов, но я не мог найти ее, поэтому я закончил ее создание. Rapidcsv - это библиотека заголовков C ++ 11, которая дает прямой доступ к разбору столбцов (или строк) в виде векторов в выбранном типе данных. Например:
#include
#include
#include
int main()
{
rapidcsv::Document doc("../tests/msft.csv");
std::vector close = doc.GetColumn("Close");
std::cout << "Read " << close.size() << " values." << std::endl;
}
Вы неправильно понимаете, как работает std::variant
operator<
. Сначала он сравнивает индексы и только если индексы равны, он сравнивает значения: https://en.cppreference.com/w/cpp/utility/variant/operator_cmp . Для неравных индексов он возвращает true
, если индекс по первому варианту меньше, чем по второму.
Это:
std::sort(std::begin(shapes), std::end(shapes));
использует сравнение по умолчанию sort
, то есть operator<
. operator<
в std::variant
определяется как как , сравнивая по индексам сначала , а затем, если оба варианта содержат одну и ту же альтернативу, сравнивая базовые значения.
Другими словами:
using V = std::variant<char, int>;
V v1(static_cast<char>(42)); // holds a char
V v2(15); // holds an int
v1 < v2; // this is true, because 'char' comes before 'int'
Итак, когда вы сортируете свои variant
, вы не сортируете по областям. Вы эффективно сортируете по кортежу (index, area)
. Который мы могли бы написать длинным путем:
std::sort(std::begin(shapes), std::end(shapes),
[](auto const& lhs, auto const& rhs)
{
auto tied = [](auto const& x) {
return std::make_tuple(
// the index
x.index(),
// the area
std::visit([](auto const& e){ return e.area(); }, x)
);
};
return tied(lhs) < tied(rhs);
});
Это дает тот же порядок, что и в вашем первоначальном примере. А затем, если вы удалите x.index()
часть кортежа, вы получите тот порядок, который вам нужен.
Но короче просто использовать многократное посещение:
std::sort(std::begin(shapes), std::end(shapes),
[](auto const& lhs, auto const& rhs)
{
std::visit([](auto const& x, auto const& y){
return x.area() < y.area();
}, lhs, rhs);
});
, которое станет еще короче в C ++ 20 с диапазонами и проекциями:
std::ranges::sort(shapes, std::less(), [](auto const& x){
return std::visit([](auto const& e){ return e.area(); }, x);
});