Friday, 4 May 2018

c++ - How to remove boilerplate in vector of tuple initialization?



I'd like to initialize a list of 5-tuples of strings like this:



std::vector >
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"}
};


This question asks why nested initializer lists can't be used for vector of tuples: the answers say to use std::make_tuple. But this makes my code look ridiculous:



std::vector >
examples =
{

std::make_tuple("/foo" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple("/foo/" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple("/foo//" ,"/" ,"foo" ,"" ,"foo"),
std::make_tuple("/foo/./" ,"/foo" ,"." ,"" ,""),
std::make_tuple("/foo/bar" ,"/foo" ,"bar" ,"" ,"bar"),
std::make_tuple("/foo/bar." ,"/foo" ,"bar." ,"" ,"bar"),
std::make_tuple("/foo/bar.txt" ,"/foo" ,"bar.txt" ,"txt","bar"),
std::make_tuple("/foo/bar.txt.zip" ,"/foo" ,"bar.txt.zip","zip","bar.txt"),
std::make_tuple("/foo/bar.dir/" ,"/foo" ,"bar.dir" ,"dir","bar"),
std::make_tuple("/foo/bar.dir/file" ,"/foo/bar.dir","file" ,"" ,"file"),

std::make_tuple("/foo/bar.dir/file.txt","/foo/bar.dir","file.txt" ,"txt","file")
};


If I can't get rid of the std::make_tuple<...>, can I at least use typedef or using to remove the clutter in the code?



using StringQuintet = std::tuple;
doesn't help because std::make_tuple<...> needs just the tuples template arguments not the tuple type.



Is there a good way to clean up this boilerplate looking mess?



Answer



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


you don't pass types to make tuple.



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


you let the compiler deduce them. Alternatively:




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


to have std string literals (using namespace std::literals; to permit this).



Or:



using StringQuintet = std::tuple;
// ...

StringQuintet("/foo" ,"/" ,"foo" ,"" ,"foo"),

No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...