On wrapping a callable in a lambda that just calls it with the same parameters

The Old New Thing (Raymond Chen) News

Summary

The article explains that wrapping a callable in a lambda is unnecessary when the inner lambda can be used directly, highlighting that C++ lambdas are syntactic sugar for classes with function call operators.

<p>Suppose you have a function that accepts a lambda and wants to use it when calling another function. I&#8217;ve seen people wrap the lambda inside another lambda:</p> <pre>template&lt;typename Lambda&gt; bool Widget::QueueToWorkerThread(Lambda&amp;&amp; lambda) { CreateWorkerThreadIfNeeded(); return m_dispatcherQueue.TryEnqueue( <span style="border: solid 1px currentcolor;">[lambda = std::forward&lt;Lambda&gt;(lambda)]() { lambda(); }</span>); } </pre> <p>But there&#8217;s no point in wrapping a lambda inside another lambda if you are just calling the inner lambda with the same parameters as the outer one. You can use the inner lambda&#8217;s function call operator directly.</p> <pre>template&lt;typename Lambda&gt; bool Widget::QueueToWorkerThread(Lambda&amp;&amp; lambda) { CreateWorkerThreadIfNeeded(); return m_dispatcherQueue.TryEnqueue( <span style="border: solid 1px currentcolor;">std::forward&lt;Lambda&gt;(lambda)</span>); } </pre> <p>My guess is that some people don&#8217;t realize that a lambda is not a special entity in the C++ language, where if somebody says that a function accepts a lambda, they think that it means that you must literally pass a lambda.</p> <p>In C++, a lambda is just syntactic sugar for a class with a function call operator. And if you already have a class with a function call operator, there&#8217;s no need to wrap it inside another class with the same function call operator.</p> <p>Wrapping a lambda is basically doing this:</p> <pre>template&lt;typename Lambda&gt; bool Widget::QueueToWorkerThread(Lambda&amp;&amp; lambda) { CreateWorkerThreadIfNeeded(); <span style="border: solid 1px currentcolor; border-bottom: none;">struct wrapper { </span> <span style="border: 1px currentcolor; border-style: none solid;"> wrapper(Lambda&amp;&amp; lambda) : </span> <span style="border: 1px currentcolor; border-style: none solid;"> m_lambda(std::forward&lt;Lambda&gt;(lambda)) {} </span> <span style="border: 1px currentcolor; border-style: none solid;"> auto operator()() const { return m_lambda(); } </span> <span style="border: 1px currentcolor; border-style: none solid;">private: </span> <span style="border: 1px currentcolor; border-style: none solid;"> const std::remove_reference_t&lt;Lambda&gt; m_lambda;</span> <span style="border: solid 1px currentcolor; border-top: none;">}; </span> return m_dispatcherQueue.TryEnqueue( wrapper(std::forward&lt;Lambda&gt;(lambda))); } </pre> <p>There&#8217;s no need to introduce the extra level of indirection. The incoming lambda is already in the form you want. Just use it.</p> <p><b>Bonus chatter</b>: Wrapping a lambda is significant if there is a transformation on the parameters, such as cocercing them to a particular type or forcing them to be passed by value.</p> <p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260819-00/?p=112624">On wrapping a callable in a lambda that just calls it with the same parameters</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
Original Article
View Cached Full Text

Cached at: 08/20/26, 03:33 PM

# On wrapping a callable in a lambda that just calls it with the same parameters - The Old New Thing Source: [https://devblogs.microsoft.com/oldnewthing/20260819-00?p=112624](https://devblogs.microsoft.com/oldnewthing/20260819-00?p=112624) Suppose you have a function that accepts a lambda and wants to use it when calling another function\. I’ve seen people wrap the lambda inside another lambda: ``` template<typename Lambda> bool Widget::QueueToWorkerThread(Lambda&& lambda) { CreateWorkerThreadIfNeeded(); return m_dispatcherQueue.TryEnqueue( [lambda = std::forward<Lambda>(lambda)]() { lambda(); }); } ``` But there’s no point in wrapping a lambda inside another lambda if you are just calling the inner lambda with the same parameters as the outer one\. You can use the inner lambda’s function call operator directly\. ``` template<typename Lambda> bool Widget::QueueToWorkerThread(Lambda&& lambda) { CreateWorkerThreadIfNeeded(); return m_dispatcherQueue.TryEnqueue( std::forward<Lambda>(lambda)); } ``` My guess is that some people don’t realize that a lambda is not a special entity in the C\+\+ language, where if somebody says that a function accepts a lambda, they think that it means that you must literally pass a lambda\. In C\+\+, a lambda is just syntactic sugar for a class with a function call operator\. And if you already have a class with a function call operator, there’s no need to wrap it inside another class with the same function call operator\. Wrapping a lambda is basically doing this: ``` template<typename Lambda> bool Widget::QueueToWorkerThread(Lambda&& lambda) { CreateWorkerThreadIfNeeded(); struct wrapper { wrapper(Lambda&& lambda) : m_lambda(std::forward<Lambda>(lambda)) {} auto operator()() const { return m_lambda(); } private: const std::remove_reference_t<Lambda> m_lambda; }; return m_dispatcherQueue.TryEnqueue( wrapper(std::forward<Lambda>(lambda))); } ``` There’s no need to introduce the extra level of indirection\. The incoming lambda is already in the form you want\. Just use it\. **Bonus chatter**: Wrapping a lambda is significant if there is a transformation on the parameters, such as cocercing them to a particular type or forcing them to be passed by value\. ### Category ### Topics ## Author ![Raymond Chen](https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2019/02/RaymondChen_5in-150x150.jpg) Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.

Similar Articles

Calling a function in C without naming it

Lobsters Hottest

A Lobsters discussion about techniques for calling a function in C without directly naming it, covering low-level language tricks and compiler/linker behavior.

C++26: More function wrappers

Lobsters Hottest

C++26 introduces two new function wrappers: std::copyable_function, which provides a copyable, const-correct alternative to std::function, and std::function_ref, a non-owning callable reference with reference semantics.

Code calling is all you need

Reddit r/AI_Agents

Argues that using code generated by LLMs to call external tools (code calling) is more efficient and capable than traditional JSON-based function calling, but requires secure sandboxing. The author is building a framework for this approach.