可变参数模板:将整数参数完美转发到 lambda
Variadic template: Perfect forwarding of integer parameter to lambda
也有类似的问题,但我没有找到适合我问题的答案。
请考虑以下代码:
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <utility>
class TestClass
{
public:
TestClass( int value): mValue( value) { }
private:
int mValue;
};
template< typename T> class DeferredCreator
{
public:
template< class... Args> DeferredCreator( Args&&... args):
mpCreator( [=]() -> T*
{ return new T( std::forward< Args>( args)...); }
),
mpObject()
{ }
T* get() {
if (mpObject == nullptr)
mpObject.reset( mpCreator());
return mpObject.get();
}
private:
std::function< T*( void)> mpCreator;
std::unique_ptr< T> mpObject;
};
int main() {
DeferredCreator< int> dcInt( 42);
assert( dcInt.get() != nullptr);
return 0;
}
这个想法是,类DeferredCreator仅在真正需要时才创建一个对象。我得到了这项工作,例如字符串,但我无法弄清楚如何将一个简单的整数传递到我的 lambda 中。
我收到的错误消息是:
prog.cpp:19:26: error: no matching function for call to 'forward'
{ return new T( std::forward< Args>( args)...); }
^~~~~~~~~~~~~~~~~~~
prog.cpp:36:27: note: in instantiation of function template specialization 'DeferredCreator<int>::DeferredCreator<int>' requested here
DeferredCreator< int> dcInt( 42);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/move.h:76:5: note: candidate function not viable: 1st argument ('const int') would lose const qualifier
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/move.h:87:5: note: candidate function not viable: 1st argument ('const int') would lose const qualifier
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
^
2 errors generated.
我已经尝试使用decltype( args)
作为std::forward<>
的模板参数,但这没有帮助。
代码也可在此处获得:https://ideone.com/MIhMkt
args...
是常量,因为lambda的调用运算符隐式const
。因此,如果您使lambda可变,那么它可以工作:
[=]() mutable -> T*
{ return new T( std::forward< Args>( args)...); }
它不适用于decltype(args)
的原因是类型本身不是const
,只是调用运算符。
lambda 表达式生成的闭包类型的operator()
是const
限定的。std::forward
可以尝试移动args...
,它们是闭包的数据成员。const
对象无法移动。
您可以将 lambda 标记为mutable
:
mpCreator( [=]() mutable -> T*
{ return new T( std::forward< Args>( args)...); }
),
这会从闭包类型的生成operator()
中删除隐式const
限定符。
wandbox.org 上的现场示例
相关文章:
- 如何反转整数参数包
- 将函数参数完美转发到函数指针:按值传递呢?
- 可变参数模板:将整数参数完美转发到 lambda
- 完美转发C++重载和模板化函子及其参数
- 完美转发可变参数模板模板
- 在完美转发函数中公开参数类型,避免代码重复
- 完美转发常量参数以进行持续评估
- 完美转发可变参数模板参数到成员函数
- 具有类模板参数推导功能的完美转发
- 使用标准::绑定在可变参数模板中完美转发引用
- (不)使用可变参数模板完美转发
- 通过对输入参数的多次传递实现完美转发
- C++ 没有与参数列表匹配的重载函数"sqrt"实例 - 试图查找结构类型的数字数组是否为完美平方
- 是否可以完美转发模板模板参数
- 我怎样才能完美地将参数转发到 STL 集合
- 修改其参数的函数的完美回报
- 函数参数绑定的完美转发和歧义
- 完美地将可变参数模板转发到标准线程
- 了解完美转发和可变参数模板的片段
- 为什么我的代码编译失败?(完美的转发和参数包)