pip*_*pex 7 c++ overloading operator-overloading implicit-conversion
考虑以下T的构造函数:
struct T {
T(const bool) { std::cout << "T(const bool)" << endl; }
T(const std::string&) { std::cout << "T(const std::string&)" << endl; }
};
T t("");
Run Code Online (Sandbox Code Playgroud)
T(const bool)优先考虑T(const std::string&)?由于上述优先级可能会导致混淆期望T(const std::string&)被调用的用户,T(const std::string&)在将字符串文字传递给T的构造函数时,我可以做什么来隐式调用.现在,我发现的唯一工作是添加另一个构造函数,最高优先权:
T(const char* s)
{
std::cout << "T(const char*)" << endl;
*this = std::string(s);
}
Run Code Online (Sandbox Code Playgroud)除了上述解决方案之外,声明explicit T(const bool)避免混淆并不能解决上述问题:在这种情况下,虽然T t = ""现在已被禁止,为什么表格T t("")仍然被允许并打电话T(const bool)?
为什么在构建时T(const bool)优先考虑?T(const std::string&)t
""属于char[1]; 这可以char const*通过数组到指针的转换隐式转换.指针可以隐式转换为bool,所有非空指针都会变为true空指针false.这些都是"内置"标准转换.
该char const* -> std::string转换是用户声明的转换:它利用的转换构造std::string,需要一个char const*.
在重载解析期间,标准("内置")转换比用户声明的转换更受欢迎,因此构造函数在bool此处的匹配比获取的更好std::string.
目前我发现的唯一工作是添加另一个构造函数
这听起来像是合理的解决方案; 对于您描述的简单场景,当然是最直接的解决方案.但是,你对作业的使用*this有点笨拙; 将两个构造函数委托给某些初始化函数会更好.
或者,您可以将模板enable_if用于任何您想要禁止转换的构造函数:
template <typename U>
T(U, std::enable_if<std::is_same<U, bool>::value>::type* = 0) { }
Run Code Online (Sandbox Code Playgroud)
此构造函数只能使用bool参数调用,而不能使用其他任何内容.你可以找到enable_if和is_same在加速,C++ TR1,或C++ 0x中.您还可以使用!is_pointer,is_integral或其他类型特征的组合来允许其他一些参数类型但不允许char const*.
或者,作为另一种选择,你可能会避开bool完全与相应的普查员使用自己的枚举true,并false为构造函数.这是否有意义取决于您的使用案例.
声明explicit T(const bool)要避免不解决上述问题...为什么表单T t("")仍然被允许并且确实调用了T(const bool)?
explicit只允许隐式转换为T. T t("");根本没有转换T; 它t通过构造它来直接初始化对象,并将参数""传递给最佳匹配的构造函数.