说明

以参数的元组调用可调用(Callable) 对象 。
元组不必是 std::tuple ,可以为任何支持 std::get 和 std::tuple_size 的类型所替代;特别是可以用 std::array 和 std::pair 。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <tuple>
#include <utility>
#include <array>
int add(int first, int second) { return first + second; }

template<typename T>
T add_generic(T first, T second) { return first + second; }

auto add_lambda = [](auto first, auto second) { return first + second; };

template<typename... Ts>
std::ostream& operator<<(std::ostream& os, std::tuple<Ts...> const& theTuple)
{
std::apply
(
[&os](Ts const&... tupleArgs)
{
os << '[';
std::size_t n{ 0 };
((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);// 展开
os << ']';
}, theTuple
);
return os;
}

std::string mergestr(const std::string& a, const std::string& b)
{
return a + b;
}

// 以参数的元组调用可调用(Callable) 对象 。
// 元组不必是 std::tuple ,可以为任何支持 std::get 和 std::tuple_size 的类型所替代;特别是可以用 std::array 和 std::pair 。

int main()
{
std::array<std::string, 2> arr;
arr[0] = "00";
arr[1] = "11";
// OK
std::cout << std::apply(mergestr, std::pair("aaa", "bbb")) << '\n';
// OK
std::cout << std::apply(mergestr, arr) << '\n';
// OK
std::cout << std::apply(add, std::pair(1L, 2L)) << '\n';
// 错误:无法推导函数类型
// std::cout << std::apply(add_generic, std::make_pair(2.0f, 3.0f)) << '\n';
// OK
std::cout << std::apply(add_generic<float>, std::make_pair(2.0f, 3.0f)) << '\n';
// OK
std::cout << std::apply(add_lambda, std::pair(3.3f, 4.4f)) << '\n';
// OK
std::cout << std::apply(add_lambda, std::tuple(4.4f, 5.5f)) << '\n';
// 进阶示例
// tuple
std::tuple<int, const char*, float, char> tuple1(1, "tuple1", 1.1f, '1');
std::tuple tuple2(2, "tuple2", 2.2f, '2'); // 自动推导类型

std::cout << tuple1 << '\n';
std::cout << tuple2 << '\n';

auto tuple3 = std::make_tuple(3, "tuple3", 3.3f, '3');
struct Foo {
Foo(int first, const char* second, float third, char fourth) {
std::cout << first << ", " << second << ", " << third << ", " << fourth << "\n";
}
};
auto f = std::make_from_tuple<Foo>(std::move(tuple3));
return 0;
}

输出

1
2
3
4
5
6
7
8
9
aaabbb
0011
3
5
7.7
9.9
[1, tuple1, 1.1, 1]
[2, tuple2, 2.2, 2]
3, tuple3, 3.3, 3

参考

https://zh.cppreference.com/w/cpp/utility/apply