Я хотел бы инициализировать список из 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<...> нужны только аргументы шаблона кортежей, а не тип кортежа.

Есть ли хороший способ навести порядок в этом беспорядке?

2
Alec Jacobson 26 Сен 2018 в 05:55

2 ответа

Лучший ответ
 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"),
3
Yakk - Adam Nevraumont 26 Сен 2018 в 03:06

Используйте std :: make_tuple:

using namespace std::string_literals;
....

std::make_tuple("/foo"s                 ,"/"s           ,"foo"s        ,""s   ,"foo"s),

....
0
Martin York 26 Сен 2018 в 03:05