我定义了以下模板,以便我可以执行明确但安全的演员:
/// 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()的临时文件仅在safe_cast期间生效,并且指针在printf内部无效(指向已被销毁的字符串临时数据)。
作为一种解决方法,我目前正在使用没有模板调用的直接强制转换:const char *c = (const char *)(obj.GetDebugName()
,但这有一个缺点,即类型安全性降低,因为强制转换不必要强大(例如,即使obj.GetDebugName,它也会默默成功()将返回int而不是字符串值)。 static_cast
可能稍微好一些,但即使这样太强大,我也希望在任何不确定安全的情况下出错。
1)如果我没有弄错,标准说临时生命时间是一个声明(除非通过绑定到const引用来扩展,在这种情况下它是引用的生命周期)。在查看上面的printf示例时,我不太清楚“声明”是什么,以及我所看到的行为是否符合。如果语句是整个printf,那么const From&amp; from的生命周期就会缩短 - 我应该从临时生命中得到什么样的生命周期?有人可以澄清吗?
2)是否有其他方法可以进行安全的转换,但结果会持续很长时间才有用?
编辑:
拜托,请考虑这是一个更普遍的问题,我正在寻找一种机制,如何在临时生命周期内完成这样的转换,我对任何特定字符串的特殊情况都不是那么感兴趣类。
澄清为什么我不想使用.c_str或类似的成员函数:我希望转换代码是类型不可知的,我不希望代码依赖于我知道这个特定的字符串类型有c_str的事实实现,我希望它工作,即使ObjectDebugName返回一个不同的字符串类,或者即使ObjectDebugName已经返回const char *(这排除了调用.operator const char *()的可能性。
答案 0 :(得分:2)
我可以执行明确但安全的演员
我会将其称为隐式强制转换,或者只是显式隐式转换。
1)如果我没有弄错,标准说临时生命时间是一个声明(除非通过绑定到const引用来扩展,在这种情况下它是引用的生命周期)。在查看上面的printf示例时,我不太清楚“声明”是什么,以及我所看到的行为是否符合。如果语句是整个printf,那么const From&amp; from的生命周期就会缩短 - 我应该从临时生命中得到什么样的生命周期?有人可以澄清吗?
你是对的,临时在 printf've返回后被销毁。 您提供的代码应该有效。如果没有,则意味着您错误地提供了一些重要信息。
答案 1 :(得分:1)
我不知道为什么你在这里使用自己的字符串类。该类是否有成员函数来获取const char *?
std :: string GetDebugName();
printf(“%s”,GetDebugName()。c_str());
是安全的,因为临时在该声明中仍然有效,例如。
答案 2 :(得分:0)
您可以直接调用转换函数:
printf("%s", obj.GetDebugName().operator const char*());