Я хотел бы инициализировать список из 5 наборов строк следующим образом:
std::vector<std::tuple<std::string,std::string,std::string,std::string,std::string> >
examples =
{
{"/foo" ,"/" ,"foo" ,"" ,"foo"},
{"/foo/" ,"/" ,"foo" ,"" ,"foo"},
{"/foo//" ,"/" ,"foo" ,"" ,"foo"},
{"/foo/./" ,"/foo" ,"." ,"" ,""},
{"/foo/bar" ,"/foo" ,"bar" ,"" ,"bar"},
{"/foo/bar." ,"/foo" ,"bar." ,"" ,"bar"},
{"/foo/bar.txt" ,"/foo" ,"bar.txt" ,"txt","bar"},
{"/foo/bar.txt.zip" ,"/foo" ,"bar.txt.zip","zip","bar.txt"},
{"/foo/bar.dir/" ,"/foo" ,"bar.dir" ,"dir","bar"},
{"/foo/bar.dir/file" ,"/foo/bar.dir","file" ,"" ,"file"},
{"/foo/bar.dir/file.txt","/foo/bar.dir","file.txt" ,"txt","file"}
};
Этот вопрос спрашивает, почему вложенные списки инициализаторов нельзя использовать для вектора кортежей: ответы говорят, что нужно использовать std::make_tuple
, Но это делает мой код смешным:
std::vector<std::tuple<std::string,std::string,std::string,std::string,std::string> >
examples =
{
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo//" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/./" ,"/foo" ,"." ,"" ,""),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar" ,"/foo" ,"bar" ,"" ,"bar"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar." ,"/foo" ,"bar." ,"" ,"bar"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar.txt" ,"/foo" ,"bar.txt" ,"txt","bar"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar.txt.zip" ,"/foo" ,"bar.txt.zip","zip","bar.txt"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar.dir/" ,"/foo" ,"bar.dir" ,"dir","bar"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar.dir/file" ,"/foo/bar.dir","file" ,"" ,"file"),
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo/bar.dir/file.txt","/foo/bar.dir","file.txt" ,"txt","file")
};
Если я не могу избавиться от std::make_tuple<...>
могу ли я хотя бы использовать typedef
или же using
убрать беспорядок в коде?
using StringQuintet = std::tuple<std::string,std::string,std::string,std::string,std::string>;
не помогает, потому что std::make_tuple<...>
нужны только аргументы шаблона кортежей, а не тип кортежа.
Есть ли хороший способ навести порядок в этом беспорядочном виде?
std::make_tuple<std::string,std::string,std::string,std::string,std::string>("/foo" ,"/" ,"foo" ,"" ,"foo"),
Вы не передаете типы для создания кортежа.
std::make_tuple("/foo" ,"/" ,"foo" ,"" ,"foo"),
вы позволяете компилятору выводить их. В качестве альтернативы:
std::make_tuple("/foo"s ,"/"s ,"foo"s ,""s ,"foo"s),
иметь строковые литералы std (using namespace std::literals;
чтобы разрешить это).
Или же:
using StringQuintet = std::tuple<std::string,std::string,std::string,std::string,std::string>;
// ...
StringQuintet("/foo" ,"/" ,"foo" ,"" ,"foo"),
Используйте std :: make_tuple:
using namespace std::string_literals;
....
std::make_tuple("/foo"s ,"/"s ,"foo"s ,""s ,"foo"s),
....