Моделирование nullptr и nullptr_t для GCC 4.5.3

По некоторым устаревшим причинам я застрял с MIPS-GCC 4.5.3. Но код, который я пытаюсь скомпилировать, сильно использует С++ 11 nullptr и nullptr_t, что отсутствует в GCC 4.5.3.

После некоторого поиска в Google и изучения использования я создал nullptr wrapper, как показано ниже, но, к сожалению, он не удовлетворяет некоторым вариантам использования,

namespace std {

class nullptr_t {
public:

nullptr_t() { }
template <typename T> nullptr_t(const T&) { }
template <class T> nullptr_t(const T*) { }
template <class T> nullptr_t(T*) { }
template <typename T, typename  U> nullptr_t(const typename T::U*) { }

template<typename T> operator T*() { return 0;}
template<typename T1, typename T2> operator T1 T2::*() { return 0; }

operator int() const { return 0; }
operator unsigned() const { return 0; }
operator bool() const { return false; }
bool operator == (unsigned i) const { return i == 0; }
bool operator != (unsigned i) const { return i != 0; }
bool operator !() const { return true; }

} nullptr = {};

}

using std::nullptr;

template<typename T> struct DummyContainer {
  DummyContainer(T* ptr)
    : m_ptr(ptr) { }

  DummyContainer(std::nullptr_t)
    : m_ptr(0) { }

  T& operator = (std::nullptr_t)  { return *m_ptr; }

  private: T* m_ptr;
};

int main(int argc, char** argv)
{
  const char* case1 = nullptr; // working
  // I think for below case std::unique_ptr has to be modified to take std::nullptr_t during construction & operator =
  std::unique_ptr<char> case2 =  nullptr; // not working. 
  DummyContainer<char> case3 = nullptr; // working
  case3 = nullptr; //working
  unsigned* case4 = argc > 1 ? nullptr : nullptr; //works


  unsigned* case5 = argc > 2 ? (unsigned*)0 : nullptr; //not working. (It is the major issue as of now)

  return 0;
}

Здесь основной случай unsigned* case5 = argc > 2 ? (unsigned*)0 : nullptr;

Снимок IDEONE: http://ideone.com/m1mhtB

(Благодаря http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf)

Любые советы/предложения будут оценены :)

(Примечание: избегайте таких ответов, как обновите gcc).


person Arunprasad Rajkumar    schedule 22.10.2013    source источник
comment
Я не уверен, что понимаю, почему вы не можете просто определить nullptr как (void*)NULL и nullptr_t как void*?   -  person Iłya Bursov    schedule 22.10.2013
comment
@ unsigned* case4 = argc › 1 ? (без знака*)0 : (недействительно*)0; точно не получится?   -  person Arunprasad Rajkumar    schedule 22.10.2013
comment
да, это даст только 0, но это будет то же самое для nullptr, или я что-то упустил в С++ 11?   -  person Iłya Bursov    schedule 22.10.2013
comment
Разве реализация Скотта Мейера не работает с gcc 4.5?   -  person Damon    schedule 23.10.2013
comment
Потратьте свою энергию и время на компиляцию последней версии GCC 4.9.1 для вашей системы. Это самый разумный поступок. Не смей использовать GCC 4.5 для С++ 11 (поскольку этот старый компилятор был выпущен до стандарта). Или же придерживайтесь C++03 и не используйте nullptr; C++11 — это гораздо больше, чем nullptr   -  person Basile Starynkevitch    schedule 30.07.2014
comment
Это проблема платформы. Поставщик чипсета не готов поддерживать последние наборы инструментов (у нас не x86, это mipsel). Поэтому мы остановились на 4.5.x. Я пробую решения на основе llvm + clang. Не уверен, насколько это возможно. stackoverflow.com/questions/24975129/   -  person Arunprasad Rajkumar    schedule 30.07.2014


Ответы (1)


Ниже решение, кажется, работает,

Исходный источник: https://code.google.com/p/chromium/codesearch#chromium/src/Third_party/WebKit/Source/wtf/NullPtr.h

namespace std {
class nullptr_t {
public:
    // Required in order to create const nullptr_t objects without an
    // explicit initializer in GCC 4.5, a la:
    //
    // const std::nullptr_t nullptr;
    nullptr_t() { }

    // Make nullptr convertible to any pointer type.
    template<typename T> operator T*() const { return 0; }
    // Make nullptr convertible to any member pointer type.
    template<typename C, typename T> operator T C::*() { return 0; }
private:
    // Do not allow taking the address of nullptr.
    void operator&();
};
}

const std::nullptr_t nullptr;

IDEOne: http://ideone.com/Bnp6th

person Arunprasad Rajkumar    schedule 22.10.2013