有类似的问题,但我没有找到适用于我的问题的答案.
请考虑以下代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我们的想法是,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.
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用decltype( args)作为模板参数std::forward<>,但这没有帮助.
代码也可以在这里找到:https://ideone.com/MIhMkt
args...是不变的,因为lambda的调用操作符是隐式的const.所以,如果你使你的lambda可变,那么它的工作原理:
[=]() mutable -> T*
{ return new T( std::forward< Args>( args)...); }
Run Code Online (Sandbox Code Playgroud)
它不能使用的原因decltype(args)是类型本身不是const,只是调用操作符.
lambda 表达式生成的闭包类型的operator()是-限定的。可以尝试移动,它们是闭包的数据成员。物体不能移动。conststd::forwardargs...const
您可以将 lambda 标记为mutable:
mpCreator( [=]() mutable -> T*
{ return new T( std::forward< Args>( args)...); }
),
Run Code Online (Sandbox Code Playgroud)
这会const从生成的闭包类型operator()中删除隐式限定符。
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |