joh*_*ash 5 c++ implicit-conversion explicit-conversion c++11 visual-studio-2013
我试图找出防止整数 0 隐式转换为 nullptr_t 然后传递给采用指针的构造函数的最佳方法。显式不会这样做,但我可以获得 nullptr_t 来导致不明确的重载错误:
#include <typeinfo.h>
struct A {
explicit A(char*) { }
};
struct B {
B(nullptr_t a) = delete;
B(char*) { }
};
int main(int argc, char* argv[])
{
A a(0); // darnit I compiled...
B b1(0); // good, fails, but with only b/c ambiguous
B b2((char*)0); // good, succeeds
B b3(1); // good, fails, with correct error
}
Run Code Online (Sandbox Code Playgroud)
还有比这更好的方法吗?另外,删除在这里到底要完成什么?
删除A(int)不会阻止A(char *)被调用
nullptr。A(nullptr_t)所以你也需要删除。
即使这样也不能保护您免于出现这样的情况:附近有一些流氓类可以从 0 或 隐式构造nullptr,并将其隐式转换为char *。
#include <iostream>
struct A {
A(int) = delete;
A(std::nullptr_t) = delete;
explicit A(char * p) {
std::cout << "Constructed with p = " << (void *)p << std::endl;
}
};
struct X
{
X(long i) : _i(i) {}
operator char *() const { return (char *)_i; }
long _i;
};
int main()
{
X x(0);
A a(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序打印:
Constructed with p = 0
Run Code Online (Sandbox Code Playgroud)
你可能认为这种可能性微乎其微,可以忽略不计。或者您可能更愿意一次性删除所有构造函数,其参数不完全属于您认可的类型。例如,假设认可的类型只是char *:
struct A {
template<typename T>
A(T) = delete;
explicit A(char * p) {}
};
struct X
{
X(long i) : _i(i) {}
operator char *() const { return (char *)_i; }
long _i;
};
int main()
{
// A a0(0);
//A a1(nullptr);
X x(0);
// A a2(x);
char *p = x;
A a3(p); // OK
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里所有注释掉的构造函数调用都无法编译。
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |