Skip to content

Commit 774d036

Browse files
committed
feat(traits): 拆分 capturable_one 并补全 std::cref 支持
- 拆出单类型 capturable_one,capturable<Ts...> 改为对其做 && 折叠, 行为完全一致(空包仍为 true),所有现有调用点无需改动 - 补全 std::cref 只读捕获:新增运行时测试(验证绑定 const 引用、 可读不写回)
1 parent face11c commit 774d036

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

taskflowlite/core/traits.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,24 @@ template <typename T>
115115
}
116116
} // namespace detail
117117

118+
/// @brief 单个类型能否被框架安全持久化存储(capturable 的逐参数原子)。
119+
///
120+
/// 满足以下任一条件即可:
121+
/// 1. 已被 std::ref/std::cref 显式包装(引用捕获);
122+
/// 2. 是右值且 decay 后可移动构造(接管临时对象所有权);
123+
/// 3. 是左值引用且 decay 后可拷贝构造(拷贝活对象)。
124+
///
125+
/// @note 这是 `capturable<Ts...>` 的单参数构件。单独暴露便于其它 concept
126+
/// 复用,也为将来的逐参数诊断留出接口。
127+
template <typename T>
128+
concept capturable_one =
129+
detail::is_reference_wrapper_after_decay_v<T> ||
130+
(!std::is_lvalue_reference_v<T> && std::is_move_constructible_v<std::decay_t<T>>) ||
131+
( std::is_lvalue_reference_v<T> && std::is_copy_constructible_v<std::decay_t<T>>);
118132

119133
/// @brief 可安全持久化存储的参数包约束。
120134
///
121-
/// 包中每个 T 满足以下任一条件:
135+
/// 包中每个 T 满足 `capturable_one<T>`:
122136
/// 1. 已被 std::ref/std::cref 显式包装(引用捕获)
123137
/// 2. 是右值且 decay 后可移动构造(接管临时对象所有权)
124138
/// 3. 是左值引用且 decay 后可拷贝构造(拷贝活对象)
@@ -130,12 +144,10 @@ template <typename T>
130144
/// - `capturable<std::string&&>` → true (情形 2)
131145
/// - `capturable<std::ref_wrapper<int>>`→ true (情形 1)
132146
/// - `capturable<std::unique_ptr<int>&>`→ false (不可拷贝构造)
147+
///
148+
/// @note 行为与拆分前完全一致(对 capturable_one 的 && 折叠)。
133149
template <typename... Ts>
134-
concept capturable = ((
135-
detail::is_reference_wrapper_after_decay_v<Ts> ||
136-
(!std::is_lvalue_reference_v<Ts> && std::is_move_constructible_v<std::decay_t<Ts>>) ||
137-
( std::is_lvalue_reference_v<Ts> && std::is_copy_constructible_v<std::decay_t<Ts>>)
138-
) && ...);
150+
concept capturable = (capturable_one<Ts> && ...);
139151

140152
/// @brief 检查是否为有效的谓词类型
141153
template <typename P, typename... Args>

test/test_flow.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,17 @@ TEST_CASE("Flow: dump outputs D2 text", "[flow][dump]") {
246246
REQUIRE(out.find("A") != std::string::npos);
247247
REQUIRE(out.find("B") != std::string::npos);
248248
}
249+
250+
/// @section std-cref-readonly —— std::cref 只读引用:可读外部,不可写回
251+
SECTION("std::cref read-only reference binds to const") {
252+
tfl::Flow flow;
253+
int outside = 7;
254+
int seen = 0;
255+
flow.emplace([&seen](const int& r) {
256+
seen = r; // 能读到外部当前值
257+
// r = 0; // 若取消注释应编译失败:const 引用不可写
258+
}, std::cref(outside));
259+
env.executor.async(flow).wait();
260+
REQUIRE(seen == 7);
261+
REQUIRE(outside == 7); // 未被改动
262+
}

0 commit comments

Comments
 (0)