Tip of the Week #59: Joining Tuples

Posted zhangyifei216

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tip of the Week #59: Joining Tuples相关的知识,希望对你有一定的参考价值。

Tip of the Week #59: Joining Tuples

Originally published as totw/59 on 2013-10-21
By Greg Miller (jgm@google.com)
Updated 2018-01-24
“Now join your hands, and with your hands your hearts.” –Henry VI, William Shakespeare

2013年的三月我们在Tips #36中宣布了一个新的string joining API,大家对于新的API的反馈是非常积极的,我们努力使这个API更好。在反馈的意见中最重要的是提供连接不同类型数据的功能。我们没有使用可变参数或者是可变模版的方式来实现,而是选择支持std::tuple,通过std::tuple间接的来支持。这很好的满足了需求。只需要创建一个包含不同类型数据的std::tuple即可,absl::StrJoin会像其它任何容器一样接收它。这里有一些例子,如下:

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), "-");

和其他任何容器一样,默认tuple中的元素是通过absl::AlphaNumFormatter这个formatted来进行格式化的,如果你的tuple中包含了默认Formatter无法格式化的类型,你可以自定义Formatter。你自定义的Formatter对象可能需要包含多个operator重载。例如:


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");

absl::StrJoinAPI的目标是通过一致的语法来join任何集合、range、list或一组数据。我们认为加入std::tuple对象非常适合这个目标,并未API增加了更多的灵活性。

以上是关于Tip of the Week #59: Joining Tuples的主要内容,如果未能解决你的问题,请参考以下文章

Tip of the Week #24: Copies, Abbrv

Tip of the Week #11: Return Policy

Tip of the Week #64: Raw String Literals

Tip of the Week #64: Raw String Literals

Tip of the Week #61: Default Member Initializers

Tip of the Week #49: Argument-Dependent Lookup