如何在元组初始化向量中删除样板?

How to remove boilerplate in vector of tuple initialization?

本文关键字:删除 向量 元组 初始化      更新时间:2023-10-16

我想初始化一个 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<...>,我至少可以使用typedefusing来消除代码中的混乱吗?

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),
....