我可以在没有首先默认构造所述成员的情况下将参数置入类成员中吗?

时间:2021-01-29 13:43:01

标签: c++ default-constructor emplace

template <typename StoredT>
class InternalObject {
public:
    using RefCountT = unsigned short;

    template <typename... CtorTs>
    static void* emplace(CtorTs&&...);

    Types type;
    RefCountT reference_count;
    bool is_immovable;
    StoredT stored_value;
    
    InternalObject();
    InternalObject(StoredT);
    ~InternalObject();
};

我的班级有一个成员 StoredT stored_value,我希望能够使用 emplace 构造它并返回一个 void*

但是,如果我想这样做,我将不得不执行 InternalObject<StoredT> *io_ptr = new InternalObject<StoredT>;,这将迫使我默认构造 stored_value

我尝试的解决方案是分配适当数量的空间作为 unsigned char 数组(返回的指针是堆指针)。然后,我尝试将指针增加适当的数量并修改那里的值。

一个更可重现和完整的示例,它不会为 two 生成有效(非 POD)值。

#include <iostream>
#include <vector>

struct S {
    int one;
    std::vector<int> two;
};

int main() {
    unsigned char *s_ptr = new unsigned char[sizeof(S)];
    S *s = reinterpret_cast<S*>(s_ptr);
    
    *s_ptr = 100; // Fine

    std::vector<int> *vec_ptr = reinterpret_cast<std::vector<int>*>(s_ptr + sizeof(int));
    *vec_ptr = {5,6,7};
    
    std::cout << s->two.capacity() << "\n"; // big ol' number

    return 0;
}

1 个答案:

答案 0 :(得分:3)

考虑使用 std::optional<StoredT>,这将允许您推迟构建您想要持有的 StoredT

#include <optional>
template <typename StoredT>
class InternalObject {
public:
    using RefCountT = unsigned short;

    template <typename... CtorTs>
    void emplace(CtorTs&&... args) {
        stored_value.emplace(args...);
    }

    Types type;
    RefCountT reference_count;
    bool is_immovable;
    std::optional<StoredT> stored_value;
    
    InternalObject();
    InternalObject(StoredT);
    ~InternalObject();
};