Как убрать шаблон в векторе инициализации кортежа? - PullRequest
0 голосов
/ 26 сентября 2018

Я хотел бы инициализировать список из 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 ]

0 голосов
/ 26 сентября 2018
 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"),
0 голосов
/ 26 сентября 2018

Использовать std :: make_tuple:

using namespace std::string_literals;
....

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

....
...