pio*_*otr 4 c++ type-conversion
在类中声明运算符std :: string时,运算符bool()如何导致错误,并且还可以作为字符串的隐式转换?
#include <iostream>
#include <string>
using namespace std;
class Test {
public:
operator std::string() { cout << "op string" << endl; return "whatever";}
operator bool() { cout << "op bool" << endl; return true;}
};
int main(int argc, char *argv[]) {
string s;
Test t;
s = t;
}
Run Code Online (Sandbox Code Playgroud)
您面临的问题(除了operator std::string()返回bool 之外)是隐式转换会在您需要时触发,而在您不需要时触发.
当编译器看到s = t它识别以下潜在std::operator=匹配时:
// using std::string for compactness instead of the full template
std::string::operator=( std::string const & );
std::string::operator=( char );
Run Code Online (Sandbox Code Playgroud)
现在,t它们都不是,所以它试图将它转换为适合的东西并找到两条路径:转换为可以升级char或std::string直接转换为bool的bool .编译器无法真正决定和放弃.
这是您希望避免提供许多不同转换运算符的原因之一.当您认为不应该被编译器隐式调用时,最终将调用任何内容.
此文章这个问题专门处理.该建议不是提供转换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;
};
Run Code Online (Sandbox Code Playgroud)
如果在condition(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;
}
Run Code Online (Sandbox Code Playgroud)
您的类现在变得更加简单,并且它本身是可读的(通过为函数和类型选择适当的名称):
// each class with conversion
class testable {
public:
operator bool_type() {
return safe_bool(true);
}
};
Run Code Online (Sandbox Code Playgroud)
只有当读者有兴趣了解safe_bool成语如何实现并读取标题时,他们才会面临复杂性(可以在评论中解释)
| 归档时间: |
|
| 查看次数: |
1594 次 |
| 最近记录: |