有一个自定义定义的映射,带有一个元素std :: function()>。 lambda代码正在运行,但是我不知道如何将其扩展为正常形式。代码如下。
class TestA{
public:
TestA() {}
~TestA() {}
TestA(const TestA &) {}
static void print()
{
cout << __FUNCTION__ << endl;
return;
}
};
void testComplexMap1()
{
typedef map<string, std::function<std::unique_ptr<TestA>()>> TempMap;
TempMap m;
// the lambda format code, it works
//m.insert({ "TestA", []() {return std::unique_ptr<TestA>(new TestA());}});
// I want to expand it, but failed.
TestA *t = new TestA();
//function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t));
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)()); //warning here
//m.emplace("TestA", fp); // compile error here
}
任何帮助将不胜感激。
答案 0 :(得分:0)
fp
未使用函数初始化,因此编译失败。
您可以像这样展开它:
TestA *t = new TestA();
std::unique_ptr<TestA> UT(t);
auto func = [&]() { return move(UT);};
std::function<std::unique_ptr<TestA>()> fp(func);
m.emplace("TestA", fp);
请参见DEMO。
答案 1 :(得分:0)
在C ++中,看起来像可能是声明的所有内容都被这样处理。 这意味着该行
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)());
解释为:
fp
是一个函数的声明,该函数返回一个std::function<unique_ptr<TestA>()>
并期望一个名为t
的参数,该参数是指向返回std::unique_ptr<TestA>
并且不获取任何参数的函数的函数指针。 (这不是您想要的。)
这也意味着此行中的t
与上一行中的t
不同。
您必须传递fp
这样实际上可以调用的东西:
std::unique_ptr<TestA> f() {
return std::make_unique<TestA>();
}
void testComplexMap1() {
// ...
function<unique_ptr<TestA>()> fp(f);
m.emplace("TestA1", fp);
}
如果要向地图添加将现有指针包装到unique_ptr
中的函数,则需要一个仿函数:
class Functor {
public:
Functor(TestA * a) : m_a(a) {}
~Functor() { delete m_a; }
std::unique_ptr<TestA> operator()(){
auto x = std::unique_ptr<TestA>(m_a);
m_a = nullptr;
return std::move(x);
}
private:
TestA * m_a;
};
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", Functor(t));
}
或带有捕获的lambda:
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", [t](){ return std::unique_ptr<TestA>(t); });
}
该lamda或多或少被翻译成Functor
类之类的东西。但是,在每种情况下,您都必须非常小心:映射中将现有指针封装到std::unique_ptr
中的函数可以并且应该仅被调用一次。
如果您不调用它们,则不会释放为t
分配的内存。如果多次调用它们,则会得到std::unique_ptr
到nullptr
(在我的Functor
类变体中)或多个std::unique_ptr
尝试管理相同的内存区域(在具有捕获变量的lambda中),第二个std::unique_ptr
被删除后,该崩溃将崩溃。
简而言之:我建议不要编写这样的代码,而只将可多次调用的函数放在映射中。