Skip to content

Replace std::bind1st/bind2nd with C++11 lambdas; target C++17#71

Merged
iagomosqueira merged 3 commits into
masterfrom
copilot/remove-deprecated-bind1st-bind2nd
May 5, 2026
Merged

Replace std::bind1st/bind2nd with C++11 lambdas; target C++17#71
iagomosqueira merged 3 commits into
masterfrom
copilot/remove-deprecated-bind1st-bind2nd

Conversation

Copilot AI commented May 5, 2026

Copy link
Copy Markdown
Contributor

std::bind1st and std::bind2nd were deprecated in C++11 and removed in C++17, causing compilation failures under C++17 toolchains. All usages are confined to scalar arithmetic operators in src/FLQuant_base.cpp.

Changes

  • src/FLQuant_base.cpp — Replace all 14 bind1st/bind2nd calls in operator+=, -=, *=, /= and the corresponding free operators with equivalent lambdas, preserving exact operand order:

    // Before
    std::transform(..., std::bind2nd(std::minus<T>(), rhs));
    std::transform(..., std::bind1st(std::minus<T>(), lhs));
    
    // After
    std::transform(..., [rhs](const T& x){ return x - rhs; });
    std::transform(..., [lhs](const T& x){ return lhs - x; });
  • src/Makevars, src/Makevars.win — Bump CXX_STD from CXX11 to CXX17.

Original prompt

Create a pull request for repository flr/FLasher to make the package compile cleanly under C++17 by removing deprecated/removed std::bind1st and std::bind2nd usage in the package's C++ sources.

Context:

  • C++ source code lives under src/ and includes headers under inst/include/.
  • src/FLQuant_base.cpp uses std::bind1st and std::bind2nd inside std::transform calls for scalar arithmetic operators (e.g., operator+=, operator-=, operator*=, operator/= and related free operators).
  • These binders were deprecated in C++11 and removed in C++17, so they must be replaced.

Required changes:

  1. Replace every usage of std::bind1st and std::bind2nd in src/FLQuant_base.cpp with equivalent C++11+ lambdas. Ensure semantics remain identical, including for overloads templated on T2 (scalar rhs) and for free operators like T - FLQuant_base<T> that currently use bind1st(std::minus<T>(), lhs).
    • For bind2nd(op, rhs): replace with [rhs](const T& x){ return x OP rhs; } (or appropriate operation).
    • For bind1st(op, lhs): replace with [lhs](const T& x){ return lhs OP x; }.
    • Keep template correctness for T and T2 (do not inadvertently narrow types). If needed, use auto in lambda parameter and decltype/std::common_type_t to preserve types.
  2. Ensure the R package is configured to compile with C++17:
    • Update/add src/Makevars and src/Makevars.win (if present) to specify CXX_STD = CXX17.
    • Do not break other compilation flags already present.
  3. Keep changes minimal and focused; do not reformat unrelated code.

Acceptance criteria:

  • No bind1st or bind2nd remain in src/.
  • Package compiles under C++17 toolchain settings.
  • CI (if present) should not be negatively impacted.

Files likely involved:

  • src/FLQuant_base.cpp
  • src/Makevars and/or src/Makevars.win (discover and update as appropriate)

Notes:

  • The repository currently uses master as default branch (badges show branch/master). Use the repository default branch as PR base.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: how can I make the C++ code in flr/FLasher follow C++17 and C++20 deprecation of std::bind?

Assistant: To make the C++ code in flr/FLasher “follow C++17/C++20” with respect to std::bind deprecation guidance, replace std::bind(...) usage with lambdas (or direct function objects) and, where applicable, switch to std::invoke/std::apply patterns. Practically, you’ll (1) find all std::bind call sites, (2) convert each to an equivalent lambda capturing what bind captured, and (3) ensure your build uses -std=c++17 or -std=c++20 so you catch remaining legacy constructs.

Because I can’t see your repository contents from what you’ve provided, below is the concrete “how” (with conversion templates) and what I’d do in that codebase. If you paste a couple of representative std::bind lines from flr/FLasher, I can rewrite them precisely.

1) Why change std::bind (and what “deprecated” means here)

  • In C++17 and C++20, std::bind is not removed, but it is widely discouraged and triggers warnings under various “deprecation / modernization” checks (e.g., clang-tidy modernize-avoid-bind). Many projects treat it as effectively deprecated.
  • Lambdas are clearer, type-safe, work better with overload resolution, and avoid placeholder confusion (_1, _2, …).

2) Find all uses

Typical search patterns:

  • std::bind
  • using namespace std::placeholders
  • _1, _2, _3 (placeholders)

3) Mechanical replacements (most common cases)

A) Binding a free function

Before

auto cb = std::bind(&doWork, _1, 42);

After

auto cb = [](auto&& x) {
  return doWork(std::forward<decltype(x)>(x), 42);
};

If you know the parameter type, prefer explicit:

auto cb = [](const Item& x) { return doWork(x, 42); };

B) Binding a member function with an object pointer

Before

auto cb = std::bind(&Worker::step, workerPtr, _1);

After

auto cb = [workerPtr](auto&& x) {
  return workerPtr->step(std::forward<decltype(x)>(x));
};

C) Binding a member function with a reference to an object

Before

auto cb = std::bind(&Worker::step, std::ref(worker), _1);

After

auto cb = [&worker](auto&& x) {
  return worker.step(std::forward<decltype(x)>(x));
};

D) Reordering / duplicating args (common “bind trick”)

Before

auto cb = std::bind(f, _2, _1);     // swap args
auto cb2 = std::bind(g, _1, _1);    // duplicate arg

After

auto cb = [](auto&& a, auto&& b) {
  return f(std::forward<decltype(b)>(b), std::forward<decltype(a)>(a));
};

auto cb2 = [](auto&& x) {
  return g(x, x);
};

E) Binding to adapt to a callback signature (event systems, threads, etc.)

Before

executor.post(std::bind(&Session::onRead, this, _1, _2));

After

executor.post([this](auto&& a, auto&...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI changed the title [WIP] Update code to remove deprecated std::bind1st and std::bind2nd Replace std::bind1st/bind2nd with C++11 lambdas; target C++17 May 5, 2026
Copilot AI requested a review from iagomosqueira May 5, 2026 08:24

@iagomosqueira iagomosqueira left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on R 4.5. and R 4.60 in Linux.

@iagomosqueira iagomosqueira marked this pull request as ready for review May 5, 2026 08:35
@iagomosqueira iagomosqueira merged commit 1376189 into master May 5, 2026
1 check passed
@iagomosqueira iagomosqueira deleted the copilot/remove-deprecated-bind1st-bind2nd branch May 5, 2026 08:35
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