Попытка использовать unique_ptr внутри объединения дает мне segfault, когда я пытаюсь выполнить std:: move или std:: make_unique.
#include <iostream>
#include <memory>
union myUnion{
struct{std::unique_ptr<float> upFloat;}structUpFloat;
struct{std::unique_ptr<int> upInt;}structUpInt;
myUnion(){}
~myUnion(){}
};
struct myStruct{
int x;
myUnion num;
};
int main()
{
myStruct aStruct, bStruct;
aStruct.x = 1;
bStruct.x = 2;
auto upF = std::make_unique<float>(3.14);
auto upI = std::make_unique<int>(3);
aStruct.num.structUpFloat.upFloat = std::move(upF);
bStruct.num.structUpInt.upInt = std::move(upI);
std::cout << "aStruct float = " << *aStruct.num.structUpFloat.upFloat << std::endl;
std::cout << "bStruct int = " << *bStruct.num.structUpInt.upInt << std::endl;
return 0;
}
Однако использование обычного указателя работает как ожидалось:
#include <iostream>
#include <memory>
union myUnion{
struct{float *pFloat;}structPFloat;
struct{int *pInt;}structPInt;
myUnion(){}
~myUnion(){}
};
struct myStruct{
int x;
myUnion num;
};
int main()
{
myStruct aStruct, bStruct;
aStruct.x = 1;
bStruct.x = 2;
auto upF = std::make_unique<float>(3.14);
auto upI = std::make_unique<int>(3);
aStruct.num.structPFloat.pFloat = upF.get();
bStruct.num.structPInt.pInt = upI.get();
std::cout << "aStruct float = " << *aStruct.num.structPFloat.pFloat << std::endl;
std::cout << "bStruct int = " << *bStruct.num.structPInt.pInt << std::endl;
return 0;
}
Это используется clang.3.4.2 или gcc.4.9.0. Поэтому я предполагаю, что здесь что-то не так. Любая помощь будет оценена.
EDIT:
Хорошо, так что, наверное, неплохо сделать, чтобы поделиться кодом, на котором я остановился. Большое спасибо всем, кто указал мне на управление временем жизни моих указателей в вариантах с использованием нового места размещения.
#include <memory>
#include <iostream>
#include <vector>
struct myStruct
{
public:
union
{
std::unique_ptr<float> upFloat;
std::unique_ptr<int> upInt;
};
enum class unionType {f, i,none} type = unionType::none; // Keep it sane
myStruct(){}
myStruct(std::unique_ptr<float> p)
{
new (&upFloat) std::unique_ptr<float>{std::move(p)};
type = unionType::f;
}
myStruct(std::unique_ptr<int> p)
{
new (&upInt) std::unique_ptr<int>{std::move(p)};
type = unionType::i;
}
~myStruct()
{
switch (type)
{
case unionType::f: upFloat.~unique_ptr<float>(); break;
case unionType::i: upInt.~unique_ptr<int>(); break;
}
}
};
int main()
{
std::vector<std::unique_ptr<myStruct>> structVec;
structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(3.14f)));
structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(739)));
structVec.push_back(std::make_unique<myStruct>());
structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(8.95f)));
structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(3)));
structVec.push_back(std::make_unique<myStruct>());
for(auto &a: structVec)
{
if(a->type == myStruct::unionType::none)
{
std::cout << "Struct Has Unallocated Union" << std::endl;
}
else if(a->type == myStruct::unionType::f)
{
std::cout << "Struct float = " << *a->upFloat << std::endl;
}
else
{
std::cout << "Struct int = " << *a->upInt << std::endl;
}
std::cout << std::endl;
}
return 0;
}
Выходы:
Struct float = 3.14
Struct int = 739
Структура нераспределенного союза
Struct float = 8.95
Struct int = 3
Структура нераспределенного союза