0

我定义了以下模板,以便我可以执行显式但安全的强制转换:

/// 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 &from 的生命周期会更短——我应该期望临时的生命周期是多少?有人可以澄清吗?

2) 是否有其他方法可以进行安全的转换,但结果的寿命足够长而有用?

编辑:

请考虑一下这更像是一种一般性问题,我正在寻找一种机制,如何针对临时生命周期进行这样的转换,我对任何特定字符串类的特殊情况不太感兴趣。

澄清为什么我不想使用 .c_str 或类似的成员函数:我希望转换代码与类型无关,我不希望代码依赖于我知道这个特定字符串类型已实现 c_str 的事实,我即使 ObjectDebugName 将返回不同的字符串类,或者即使 ObjectDebugName 已经返回 const char *(这排除了调用 .operator const char *() 的可能性,也希望它能够工作。

4

3 回答 3

2

我可以执行明确但安全的演员表

我会称它为显式完成的隐式转换,或者只是和显式的隐式转换。

1)如果我没记错的话,标准说临时生命周期是一个声明(除非通过绑定到 const 引用来扩展,在这种情况下它是引用的生命周期)。查看上面的 printf 示例时,我不太确定“语句”是什么,以及我看到的行为是否符合要求。如果语句是整个 printf,则 const From &from 的生命周期会更短——我应该期望临时的生命周期是多少?有人可以澄清吗?

你是对的, printf返回后临时文件被销毁。您提供的代码应该可以工作。如果没有,则表示您错误提供了一些重要信息。

于 2010-11-23T10:52:56.663 回答
1

我不知道你为什么在这里使用自己的字符串类。该类是否有一个成员函数可以从中获取 const char * ?

std::string GetDebugName();

printf("%s", GetDebugName().c_str());

将是安全的,因为例如在该语句期间临时将保持有效。

于 2010-11-23T10:33:15.983 回答
0

可以直接调用转换函数:

printf("%s", obj.GetDebugName().operator const char*());
于 2010-11-23T10:39:08.543 回答