你面临的问题(除了operator std::string()
返回一个布尔值)是隐式转换触发,当你想要和当你不需要。
当编译器看到s = t
它确定了以下潜在std::operator=
比赛:
// using std::string for compactness instead of the full template
std::string::operator=(std::string const &);
std::string::operator=(char);
现在,t
既不是他们的,所以它试图转换的东西,可以适应,发现两条路径:转换为可以升级到char
或直接转换为std::string
的bool。编译器不能真正决定并放弃。
这是您希望避免提供许多不同转换运算符的原因之一。任何可以被编译器隐式调用的东西最终都会在你认为不应该的时候调用。
这个article专门处理这个问题。该建议是,而不是提供一个转换到bool
,提供一个转换到一个成员函数
class testable {
typedef void (testable::*bool_type)();
void auxiliar_function_for_true_value() {}
public:
operator bool_type() const {
return condition() ? &testable::auxiliar_function_for_true_value : 0;
}
bool condition() const;
};
如果这个类的一个实例是一个条件(if (testable())
)编译器会尝试,并转换为bool_type
,可以是内部使用在条件下使用。
编辑:
的代码是如何与这个解决方案更加复杂的评论后,可以随时为它作为一个普通的小工具。一旦你提供了代码的第一部分,复杂性就被封装在头文件中。
// utility header safe_bool.hpp
class safe_bool_t;
typedef void (safe_bool_t::*bool_type)();
inline bool_type safe_bool(bool);
class safe_bool_t {
void auxiliar_function_for_true_value() {}
friend bool_type safe_bool(bool);
};
inline bool_type safe_bool(bool)
{
return condition ? &safe_bool_t::auxiliar_function_for_true_value : 0;
}
你的类现在变得更加简单,而且它本身就是可读(通过为功能和类型选择合适的名称):
// each class with conversion
class testable {
public:
operator bool_type() {
return safe_bool(true);
}
};
只有当读者想知道如何safe_bool
成语实现并读取它们填充的头部将面临的复杂性(可在注释中解释)
如果你打算继续'使用命名空间标准;'你为什么要继续澄清'std :: string'? – 2010-02-19 08:33:21