В 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));
}
Или лямбда с захватом:
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", [t](){ return std::unique_ptr<TestA>(t); });
}
Лямда более или менее переводится в нечто вроде Functor
класса.Однако в каждом случае вы должны быть очень осторожны: функции на карте, которые инкапсулируют существующий указатель в std::unique_ptr
, могут и должны вызываться только один раз.
Если вы не вызываете их, выделяется памятьдля t
не будет освобожден.Если вы вызываете их более одного раза, вы получаете либо std::unique_ptr
- nullptr
(в моем варианте Functor
класса), либо более одного std::unique_ptr
пытается управлять одной и той же областью памяти (в лямбда-режиме с вариантом захвата), которая вылетает, как только удаляется вторая std::unique_ptr
.
Короче говоря: я бы посоветовал не писать такой код и ставить на карту только те функции, которые можно вызывать несколько раз.