Finding a Pointer to NULL

拜拜、爱过 提交于 2020-01-05 04:33:07

问题


I have int* foo[SIZE] and I want to search it for the first element that points to NULL.

But when I do this:

 std::find(foo, foo + SIZE, NULL)

I get the error:

error C2446: '==' : no conversion from 'const int' to 'int *'

Should I just be using static_cast<int*>(NULL) instead of NULL?

C++11 solves this via nullptr but that's not an option for me in C++03


回答1:


tl;dr: Use nullptr, or define your own equivalent.


The problem is that NULL is some macro that expands to an integral constant expression with value zero. In order to call the function, std::find has to deduce the type and use the value (0).

You cannot compare int* with int, hence the error. As far as the function is concerned, you just passed it some regular old int that happens to be zero, and those cannot be converted to null pointers; they have to be integral constant expressions.

Normally NULL "works" because it's used in contexts where it isn't treated just as its integer form, e.g.:

if (ptr == NULL)

Because here it maintains its "integral constant expression" status, so converts to a null pointer of the compared-to type.

You should use nullptr if you're in C++11 or beyond, because this is actually a null pointer, not an integer that converts to it. What you've described is actually one of the motivating factors for introducing nullptr.

There are various C++03 implementations of nullptr if you need one. I have attached the classic implementation at the bottom of this answer.

Also, you should prefer std::array if possible (Boost has one if you need it), or at the very least use std::begin and std::end to get the array begin and end pointers (and again, there are implementations of this floating around):

#include <algorithm>
#include <array>

int main() {
    std::array<int*, 8> foo = {};
    std::find(foo.begin(), foo.end(), nullptr);
}

All said, in a pinch casting to the null pointer of your type is a valid solution. nullptr is really just a short-hand for "a thing that converts to the null pointer of the needed type".


Here is a nullptr implementation, initially created by Scott Meyers:

const
struct nullptr_t {
    template <typename T>
    operator T*() const {
        return 0;
    }

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

  private:
    void operator&() const;

} nullptr = {};

The syntax looks a bit funny because we don't usually define a class and a variable at the same time. Obviously if you want to stay C++11 compatible, nullptr isn't a usable identifier. null_ptr or nullpointer are good alternatives.




回答2:


This problem is actually called out in Herb Sutter and Bjarne Stroustrup's: A name for the null pointer: nullptr:

Distinguishing between null and zero. The null pointer and an integer 0 cannot be distinguished well for overload resolution. For example, given two overloaded functions f(int) and f(char*), the call f(0) unambiguously resolves to f(int). There is no way to write a call to f(char*) with a null pointer value without writing an explicit cast (i.e., f((char*)0)) or using a named variable

So we see that this problem can be solved by either:

  1. An explicit cast
  2. The declaration of a value with matching type, for example: const int* piNULL = NULL

Ideally when using the explicit cast a C-Style cast can be avoided. Either of these C++-Style casts effectively returns an int* containing address NULL:

  • reinterpret_cast<int*>(NULL)
  • static_cast<int*>(NULL)

http://en.cppreference.com/w/cpp/types/NULL asserts that:

A null pointer constant may be implicitly converted to any pointer type; such conversion results in the null pointer value of that type

And since static_cast:

Converts between types using a combination of implicit and user-defined conversions

static_cast more closely defines the type of cast intended than does reinterpret_cast which:

Converts between types by reinterpreting the underlying bit pattern

So, in C++03 static_cast<int*>(NULL) is the tightest inline definition of C++11's nullptr that can be achieved.



来源:https://stackoverflow.com/questions/40031426/finding-a-pointer-to-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!