特别是,我希望以下代码失败:
void a(void*){}
int main(){
a(0); // FAIL
a(NULL); // FAIL
a(nullptr); // success
}
而且我想编译以下代码:
void a(int){}
void a(void*){}
int main(){
a(0); // calls first a
a(NULL); // calls first a; that's why I have -Werror
a(nullptr); // calls second a
}
以下代码当前无法编译,但应根据我的规则:
void a(std::size_t){}
void a(void*){}
int main(){
a(0); // two candidates
}
任何想法如何使g ++那样表现?
这可能不是完美的,但是如果您确实想要int和指针重载,则可以使用如下这样的辅助类:
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
template<typename T = void> class ptr {
T* it;
public:
ptr(T* it = nullptr): it(it) {}
ptr(const ptr<T>&) = default;
ptr& operator = (const ptr<T>&) = default;
operator T* () { return it; }
T& operator * () { return *it; }
T* operator -> () { return it; }
ptr& operator += (int x) { it += x; return *this; }
ptr& operator -= (int x) { it -= x; return *this; }
ptr& operator ++ () { ++it; return *this; }
// etc...
public:
template<typename P>
ptr(P* it): it(it) {}
template<typename P>
ptr(ptr<P> it): it((T*)it) {}
};
template<> class ptr<void> {
void* it;
public:
ptr(void* it = nullptr): it(it) {}
ptr(const ptr<void>&) = default;
ptr& operator = (const ptr<void>&) = default;
operator void* () { return it; }
public:
template<typename P>
ptr(P* it): it(it) {}
template<typename P>
ptr(ptr<P> it): it((void*)it) {}
};
void a(std::size_t x) {
cout << "first: " << x << endl; }
void a(ptr<const int> p) {
cout << "second: " << (p ? *p : -1) << endl; }
void a(ptr<int> p, ptr<> q) {
cout << "third: " << (p ? *p : -1) << ", "
<< (q ? "some" : "null") << endl;
a(p); }
int main(){
a(0); // first: 0
a(NULL); // first: 0 but warning [-Wconversion-null]
a(new int(3), nullptr); // third: 3, null + second: 3
}
还没有完成(也许删除该显式,添加更多的运算符,从nullptr_t进行特殊转换,等等),公正和想法。
EDIT:
代码,模板构造函数和转换为ptr<const int>
测试的更改很少。当您使用0或-Wzero-as-null-pointer-constant
而不是NULL
时,可以用nullptr
进行编译以获得警告。为了将其升级为错误,我相信可以使用-Werror=zero-as-null-pointer-constant
。
鉴于NULL
与NULL
或0
相同,我认为您不能强迫C ++编译器按照描述的方式运行。我可以想象使用nullptr
的AST接口完全按照您的描述来检测案例。我希望典型的C ++代码将包含clang和/或0
的一些有意用法,以酌情表示指针和/或整数。
这是第一个问题的相对简单的解决方案(需要C ++ 11):
用途: