我想创建一个使用签名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
的提供者联系以找到解决方案。我将把这个问题留给后代。
答案 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