c ++: данные в стеке без их инициализации - PullRequest
0 голосов
/ 31 января 2019

Я хочу создать адаптер, который использует функцию подписи 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 голосов
/ 31 января 2019

Поскольку 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
0 голосов
/ 31 января 2019

(*out = {...}) это не инициализирует.

Назначение и инициализация не одно и то же.Назначение неинициализированных данных - это UB в тех случаях, когда вы пытаетесь оптимизировать.

Вы можете размещать новые для инициализации, но поскольку вы не можете изменить тело преобразования, это не разрешено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...