In the code snippet below, the comparison (nullptr == pmf) in main should compile but on gcc it fails to compile. Compiler fails to find appropriate conversion operator and gives error saying: error: no match for operator== in nullptr == pmf class nullptr_t { public: template<class T> operator T*() const // convertible to any type of null non-member pointer... { return 0; } template<class C, class T> operator T C::*() const // or any type of null member pointer... { return 0; } } nullptr = {}; struct C { void func (); }; int main(void) { char * ch = nullptr; void (C::*pmf)() = nullptr; if (nullptr == ch) {} // Compiles successfully if (nullptr == pmf) {} // Should compile but does not compile on gcc 4.1.1 }
Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.1 20070105 (Red Hat 4.1.1-51)
Confirmed with 2.95 and 4.2.1. W.
(In reply to comment #0) There is a makeshift. File a.cpp #include <stdio.h> const class nullptr_t { public: template<class T> operator T*() const { return 0; } template<class C, class T> operator T C::*() const { return 0; } // void (C::*pmf)() = nullptr; // Ok // if (nullptr == pmf) {} // Ok template<class C, class T> bool operator == (C (T::*p)()) const { return p == 0; } private: void operator&() const; // const int n = 0; // if (nullptr == n) {} // Error bool operator == (long) const; } nullptr = {}; struct C { void func(); }; int main(void) { void (C::*pmf)() = nullptr; if (nullptr == pmf) {printf("Ok\n");} // If there are sentences - send !!!!!!!! // if (pmf == nullptr) {printf("Ok\n");} // Error } > g++ a.cpp > ./a.out Ok >
current 4.5 rejects all conversions: $ cat t.cpp const // this is a const object... class { public: template<class T> // convertible to any type operator T*() const // of null non-member { return 0; } // pointer... template<class C, class T> // or any type of null operator T C::*() const // member pointer... { return 0; } private: void operator&() const; // whose address can't be taken } nullptr = {}; // and whose name is nullptr extern void* p; struct A { void foo(); }; extern void (A::*pmf)(); int main() { return ( ( p != nullptr ) && ( pmf != nullptr ) ); } $ g++ t.cpp -std=c++0x -c t.cpp: In function 'int main()': t.cpp:22:19: error: no match for 'operator!=' in 'p != nullptr' t.cpp:22:41: error: no match for 'operator!=' in 'pmf != nullptr'
N.B. nullptr is a keyword in c++0x, and proper nullptr support has been added to 4.6 anyway, but those covnersions should still work
(In reply to comment #5) > N.B. nullptr is a keyword in c++0x, and proper nullptr support has been added > to 4.6 anyway, but those covnersions should still work gcc <= 4.4 rejects only operator!=(pmf,nullptr): $ g++44 t.cpp -Wall -c -std=c++0x t.cpp: In function 'int main()': t.cpp:21: error: no match for 'operator!=' in 'pmf != nullptr' gcc >= 4.5 rejects also operator!=(p,nullptr): $ g++45 t.cpp -Wall -c -std=c++0x t.cpp: In function 'int main()': t.cpp:21:19: error: no match for 'operator!=' in 'p != nullptr' t.cpp:21:41: error: no match for 'operator!=' in 'pmf != nullptr'