string_viewoperator+ vs. StrCat()absl::Statusstd::bindabsl::optional and std::unique_ptrabsl::StrFormat()make_unique and private Constructors.boolexplicit= delete)switch Statements Responsibly= deleteAbslHashValue and Youcontains()std::optional parametersif and switch statements with initializersinline Variablesstd::unique_ptr Must Be MovedAbslStringify()vector.at()auto for Variable DeclarationsOriginally published as totw/59 on 2013-10-21
By Greg Miller ([email protected])
Updated 2018-01-24
“Now join your hands, and with your hands your hearts.” –Henry VI, William Shakespeare
In March, 2013 we announced the new string joining
API in Tip #36. The response to the new API was quite
positive, and we worked to make the API even better. Topping the list of
feature requests was the ability to join arbitrary lists of possibly
heterogeneous data (I can only assume that Shakespeare was referring to
joining a heterogeneous collection of hands and hearts). We didn’t go with
the varargs or variadic template route, but we did add support for joining
std::tuple objects, which addresses this need quite nicely. Simply create
a std::tuple containing your heterogeneous data, and absl::StrJoin()
will accept it just like any other container. Here are a few examples:
auto tup = std::make_tuple(123, "abc", 0.456);
std::string s = absl::StrJoin(tup, "-");
s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
int a = 123;
std::string b = "abc";
double c = 0.456;
// Works, but copies all arguments.
s = absl::StrJoin(std::make_tuple(a, b, c), "-");
// No copies, but only works with lvalues.
s = absl::StrJoin(std::tie(a, b, c), "-");
// No copies, and works with lvalues and rvalues.
s = absl::StrJoin(std::forward_as_tuple(123, MakeFoo(), c), "-");
As with joining any container, the elements of the tuple are formatted using an
absl::AlphaNumFormatter by default, but you can specify a custom
join Formatter if your tuple contains elements that are not
handled by the default formatter. To format a tuple with multiple custom
element types, your custom Formatter object may contain multiple overloads
of operator().
For example:
struct Foo {};
struct Bar {};
struct MyFormatter {
void operator()(string* out, const Foo& f) const {
out->append("Foo");
}
void operator()(string* out, const Bar& b) const {
out->append("Bar");
}
};
std::string s = absl::StrJoin(std::forward_as_tuple(Foo(), Bar()), "-",
MyFormatter());
EXPECT_EQ(s, "Foo-Bar");
The goal of the absl::StrJoin() API is to join any collection, range, list, or
group of data using an intuitive and consistent syntax. We think joining
std::tuple objects fits nicely with this goal and adds more flexibility to the
API.