我有几个类似字符串的类,可以隐式转换为字符串。我对这些有一些用处;一个例子是保存需要在运行时由gettext翻译的文本:
class TranslatableString
{
public:
explicit TranslatableString(const char *s) : native_text_(s) {}
operator const char *() const { return gettext(native_text_); }
// Or not - see below:
operator const std::string() const { return gettext(native_text_); }
private:
const char * const native_text_;
};
现在我正在努力使这个类尽可能简单(即,使用它应尽可能像字符串文字)。特别是,我希望以下两个示例用法都可以使用:
const TranslatableString HELLO = TranslatableString("Hello, world!");
std::string ExampleA() {
return HELLO;
}
void ExampleB() {
std::string s;
s = HELLO;
}
有没有办法让两个例子都有效?
operator std::string
,那么ExampleB无法编译,说std::string::operator=(const char *)
和std::string operator=(const std::string&)
之间存在歧义(这是有道理的)。operator std::string
,那么ExampleA无法编译;显然隐式地将TranslatableString转换为const char *到std :: string是不允许的,虽然我不太了解C ++的隐式转换规则来解释原因。答案 0 :(得分:5)
每个转换序列中只允许一次用户定义的转化,这就是为什么你不能“通过”const char*
。 (请注意,const char*
到std::string
也是用户定义的转化。)
您需要转换为const char*
吗?如果没有它(并且转换为std::string
),这两个例子都可行。
在内部将数据存储为std::string
而不是const char*
也可能值得考虑。您不必担心解除分配问题,数据“消失”在您手中等等。
答案 1 :(得分:1)
你必须放弃operator const char *
。将其设为explicit
(C ++ 11)或将其作为c_str
方法提供。
不允许将TranslatableString
转换为const char *
到std::string
,因为它包含两个用户定义的转化。