c ++:堆栈中的数据未初始化

时间:2019-01-31 09:43:16

标签: c++ memory

我想创建一个使用签名void convert(void* input, T* out, int* ok)函数的适配器,其中T重载为任何类型,ok指示是否发生错误(提供了这些函数,我无法更改其功能身体)。模板内部功能的摘要:

template<typename T>
T convert_adapter(void* input){
    T result;
    int ok = 1;
    convert(input, &result, &ok);
    if (!ok)
        throw Exception("error during conversion");
    return result;
}

这对于int和简单结构之类的类型足够好,但是在没有默认构造函数的更复杂的类和结构上失败,因为result无法在第一行中默认初始化。问题是,如果convert中发生错误,我不使用result,并且如果没有发生错误,convert将为result分配一个初始化值本身(*out = {...}),所以我不需要自己真正初始化result

如何为convert提供一个指向未初始化数据的指针,并将其指向适当的类型?我知道我可以用char[sizeof(T)]来做到这一点,但我想知道是否有更优雅的解决方案。

编辑:我现在看到此问题与C ++的一些基本概念背道而驰,我将尝试与convert的提供者联系以找到解决方案。我将把这个问题留给后代。

2 个答案:

答案 0 :(得分:1)

(*out = {...})这不会初始化。

赋值和初始化不是一回事。在您要优化的情况下,分配给未初始化的数据就是UB。

您可以放置​​new进行初始化,但是由于您不能更改convert的主体,因此不允许这样做。

答案 1 :(得分:0)

无论如何返回result,为什么不更改convert_adapter的签名?您可以将其作为输出参数而不是返回值:

template<typename T>
convert_adapter(void* input, T* result){
    int ok = 1;
    convert(input, result, &ok);
    if (!ok)
        throw Exception("error during conversion");
    return;
}

这样,您可以在result之外的地方初始化convert_adapter,在这里可以使用非默认构造函数。由于您可能想将结果分配给某物,因此无论如何在您调用T的地方都必须存在类型convert_adapter的变量。

T result(non,default,contructor,parameter,values);
//result = convert_adapter(input); // old
convert_adapter(input, &result); // new