void output_list_contents(std::list<tuple<string, int, double,int>> &my_list)
{
for(std::list<tuple<string, int, double,int> >::iterator it =my_list.begin(); it!= my_list.end(); ++it)
{
}
}
Я пытаюсь вывести информацию из всех кортежей, хранящихся в списке STL. Я не знаю синтаксиса, и я потратил прошлый час на поиски Google, но, к сожалению, я ничего не встречал. Я борюсь с синтаксисом и логикой, чтобы получить доступ к кортежам, хранящимся внутри.
Может ли кто-нибудь помочь мне здесь, пожалуйста?
Что-то вроде:
void output_list_contents(std::list<tuple<string, int, double,int>> &my_list)
{
for(const auto& e : my_list)
{
std::cout << std::get<0>(e) << " " << std::get<1>(e) << " "
<< std::get<2>(e) << " " << std::get<3>(e) << std::endl;
}
}
Первый operator<<
перегрузки operator<<
для tuple<string, int, double,int>
:
std::ostream& opertaor<<(std::ostream& out,
tuple<string,int,double,int> const & t)
{
return out << "{" << std::get<0>(t)
<< "," << std::get<1>(t)
<< "," << std::get<2>(t)
<< "," << std::get<3>(t) << "}";
}
затем используйте его в цикле как:
for(std::list<tuple<string, int, double,int> >::iterator it =my_list.begin();
it!= my_list.end(); ++it)
{
std::cout << *it << std::endl;
}
О, это уродливо. Лучше использовать диапазон for
цикла и auto
:
for(auto const & item : my_list)
std::cout << item << std::endl;
Надеюсь, это поможет.
Обобщенная реализация operator<<
для std::tuple
будет std::tuple
:
namespace detail
{
template<int ... N>
struct seq
{
using type = seq<N...>;
template<int I>
struct push_back : seq<N..., I> {};
};
template<int N>
struct genseq : genseq<N-1>::type::template push_back<N-1> {};
template<>
struct genseq<0> : seq<> {};
template<typename ... Types, int ...N>
void print(std::ostream & out, std::tuple<Types...> const & t, seq<N...>)
{
const auto max = sizeof...(N);
auto sink = {
(out << "{", 0),
(out << (N?",":"") << std::get<N>(t) , 0)...,
(out << "}", 0)
};
}
}
template<typename ... Types>
std::ostream& operator<<(std::ostream & out, std::tuple<Types...> const & t)
{
detail::print(out, t, typename detail::genseq<sizeof...(Types)>::type());
return out;
}
Этот обобщенный operator<<
должен иметь возможность печатать std::tuple
с любым количеством аргументов шаблона, если все аргументы шаблона поддерживают operator<<
в свою очередь.
Тестовый код:
int main()
{
std::cout << std::make_tuple(10, 20.0, std::string("Nawaz")) << std::endl;
std::cout << std::make_tuple(10, 20.0, std::string("Nawaz"), 9089) << std::endl;
}
Вывод:
{10,20,Nawaz}
{10,20,Nawaz,9089}
Демо- версия :-)
void output_list_contents(std::list<std::tuple<std::string, int, double, int>>& my_list)
{
for (auto tup : my_list)
{
print_tuple(tup);
}
}
И вот как выглядит print_tuple
:
template <typename... Ts, int... Is>
void print_tuple(std::tuple<Ts...>& tup, std::index_sequence<Is...>)
{
auto l = { ((std::cout << std::get<Is>(tup)), 0)... };
}
template <typename... Ts>
void print_tuple(std::tuple<Ts...>& tup)
{
print_tuple(tup, std::index_sequence_for<Ts...>{});
}
const auto&
просто связывает элемент на основе содержимого контейнера, следовательно,auto
выводит кортеж в вашем примере.const auto&
используется вместоauto
чтобы избежать копирования кортежей при повторенииlist
.