У меня есть следующий шаблон, определенный для того, чтобы я мог выполнять явное, но безопасное приведение:
/// cast using implicit conversions only
template <class To,class From>
inline To safe_cast( const From &from ) {return from;}
Часто (например, при передаче аргументов в sprintf и аналогичные функции) я хотел бы использовать этот шаблон длявыполнить преобразование из строкового класса в строку в стиле c.Однако это показывает, что это невозможно при передаче временного значения, поскольку временное не будет существовать достаточно долго.
Рассмотрим следующий пример:
class Object
{
public:
MyStringClass GetDebugName() const;
};
Object obj;
printf("%s",safe_cast<const char *>(obj.GetDebugName()));
Временный объект из obj.GetDebugName () lifeтолько во время safe_cast и указатель недействителен (указывает на данные строки, которая уже была уничтожена), когда находится внутри printf.
В качестве обходного пути я в настоящее время использую прямое приведение без вызова шаблона:const char *c = (const char *)(obj.GetDebugName()
, но это имеет недостаток, заключающийся в снижении безопасности типов, так как приведение является чрезмерно сильным (например, оно молча преуспеет, даже если obj.GetDebugName () будет возвращать int вместо строкового значения).static_cast
может быть немного лучше, но даже если это слишком сильно, я хотел бы получить ошибку в любой ситуации, когда приведение не обязательно будет безопасным.
1) Если я не ошибаюсь, стандартговорит, что временное время жизни - это утверждение (если оно не расширено привязкой к константной ссылке, в этом случае это время жизни ссылки).Глядя на приведенный выше пример printf, я не совсем уверен, что такое «утверждение», и соответствует ли поведение, которое я видел, или нет.Если оператор является целым printf, время жизни const From & from короче - какое время жизни я должен ожидать от временного?Кто-то может уточнить?
2) Есть ли другой способ сделать преобразование, которое было бы безопасным, но результат мог бы прожить достаточно долго, чтобы быть полезным?
Редактировать:
Пожалуйста, рассмотрите это скорее как общий вопрос, я ищу механизм, как можно сделать подобное преобразование в отношении временного времени жизни, меня не очень интересует особый случай какого-либо конкретного строкового класса.
Чтобы прояснить, почему я не хочу использовать .c_str или аналогичную функцию-член: я хотел бы, чтобы код преобразования был независимым от типа, я не хочу, чтобы код полагался на факт, что я знаю эту конкретную строкуТип реализован c_str, я хочу, чтобы он работал, даже если ObjectDebugName вернет другой класс строки, или даже если ObjectDebugName уже возвращает const char * (что исключает возможность вызова .operator const char * ().