安全转换为const char * - 临时生命周期问题

时间:2010-11-23 10:12:18

标签: c++ casting temporary

我定义了以下模板,以便我可以执行明确但安全的演员:

/// 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 *()的可能性。

3 个答案:

答案 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*());