Skip to content

fix(bytes): replace std::forward<D>(d) with std::move(d) in move constructors#776

Merged
YuanYuYuan merged 1 commit intoeclipse-zenoh:mainfrom
ZettaScaleLabs:fix/msvc-bytes-forward
Apr 14, 2026
Merged

fix(bytes): replace std::forward<D>(d) with std::move(d) in move constructors#776
YuanYuYuan merged 1 commit intoeclipse-zenoh:mainfrom
ZettaScaleLabs:fix/msvc-bytes-forward

Conversation

@YuanYuYuan
Copy link
Copy Markdown
Contributor

@YuanYuYuan YuanYuYuan commented Apr 14, 2026

Summary

  • Replace std::forward<D>(d) with std::move(d) in three Bytes move constructors in bytes.hxx

Root Cause

MSVC 19.44 (VS 2022 17.14, shipped with the ROS 2 buildfarm) rejects the pattern:

auto d = [p = ptr]() mutable { delete p; };
using D = decltype(d);
auto drop = DroppableType::into_context(std::forward<D>(d));  // C2665 / C3536

When D is deduced as decltype(d) — a local lambda type — it is always a non-reference type. std::forward<D>(d) then expects a D&& argument, but MSVC 19.44 refuses to convert the lvalue d to D&&, reporting:

error C2665: 'std::forward': no overloaded function could convert all the argument types
error C3536: 'drop': cannot be used before it is initialized

This is a conformance tightening introduced in a recent MSVC toolset update. Since D is never a reference here, std::forward<D> is semantically identical to std::move. Using std::move(d) is unambiguous and correct on all compilers.

Affected constructors

  • Bytes(std::vector<uint8_t, Allocator>&&) — line 71
  • Bytes(std::string&&) — line 96
  • Bytes(uint8_t*, size_t, Deleter) — line 115

Context

This broke the ROS 2 buildfarm Windows CI when rmw_zenoh_cpp instantiates these constructors. Tracked in the ROS 2 PMC discussion and visible at:
https://ci.ros2.org/job/ci_windows/27547/

The fix is minimal — 3 lines changed, no behavior change on any compiler.

Breaking Changes

None

…tructors

MSVC 19.44 (VS 2022 17.14) rejects std::forward<D>(d) when D is deduced
as decltype(d) — a local lambda type (always non-reference). The compiler
cannot convert the lvalue lambda to D&&, yielding C2665/C3536.

std::move(d) is the correct form here: D is never a reference type in
these constructors so std::forward<D> is semantically equivalent to
std::move, but newer MSVC enforces the distinction.

Affects three Bytes constructors:
- Bytes(std::vector<uint8_t, Allocator>&&)
- Bytes(std::string&&)
- Bytes(uint8_t*, size_t, Deleter)

Fixes ROS 2 buildfarm Windows build failure:
https://ci.ros2.org/job/ci_windows/27547/
@YuanYuYuan YuanYuYuan requested review from DenisBiryukov91 and milyin and removed request for DenisBiryukov91 April 14, 2026 07:28
@YuanYuYuan YuanYuYuan merged commit a3cd1a2 into eclipse-zenoh:main Apr 14, 2026
27 checks passed
YuanYuYuan added a commit to ZettaScaleLabs/rmw_zenoh that referenced this pull request Apr 14, 2026
eclipse-zenoh/zenoh-cpp#776 fixed std::forward<D>(d) → std::move(d)
in three Bytes move constructors. MSVC 19.44 (VS 2022 17.14, used by
the ROS 2 Windows buildfarm) rejects std::forward on deduced lambda
types with C2665/C3536. The fix is merged at a3cd1a2d.

Bump zenoh_cpp_vendor to that commit to unblock ci_windows builds.
YuanYuYuan added a commit to ZettaScaleLabs/rmw_zenoh that referenced this pull request Apr 14, 2026
eclipse-zenoh/zenoh-cpp#776 fixed std::forward<D>(d) → std::move(d)
in three Bytes move constructors. MSVC 19.44 (VS 2022 17.14, used by
the ROS 2 Windows buildfarm) rejects std::forward on deduced lambda
types with C2665/C3536. The fix is merged at a3cd1a2d.

Bump zenoh_cpp_vendor to that commit to unblock ci_windows builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants