【问题标题】:Can I cast nullptr to other pointer type?我可以将 nullptr 转换为其他指针类型吗?
【发布时间】:2015-11-11 14:26:58
【问题描述】:

我可以这样做吗?

static_cast<A*>(getSomePtr());

getSomePtr() 将返回 nullptr。这样可以吗?

【问题讨论】:

  • 这就是nullptr 的用途。
  • getSomePtr()的返回类型是什么?它实际上是std::nullptr_t 还是某些实际指针类型的空指针值?从函数返回std::nullptr_t 很奇怪,如果它不是std::nullptr_t,那么你不需要转换它,因为它不是nullptr
  • 重要的是类型。指针的值不影响强制转换是否有效。
  • 这完全取决于“其他指针类型”的含义。还有,你的意思是空指针还是nullptr?它们是不同的东西。将返回类型显式写入问题会很有用。
  • 你不需要一个函数来返回nullptrnullptr的值的类型只承认一个值,也就是那个值,所以你不妨把函数替换为该值的常数。

标签: c++ c++11


【解决方案1】:

来自Wikipedia article

...空指针常量:nullptr。它是类型 nullptr_t,它是隐式可转换的,可与任何 指针类型或指向成员的指针类型。它不是隐含的 可转换或可比较的整数类型,bool 除外。

nullptr 可以隐式转换为任何指针类型,因此使用static_cast 进行显式转换绝对有效。

【讨论】:

  • 您是否将“冗余”定义为 OK?
  • @zenith 我正在回答这个问题。函数getSomePtr() 可以返回nullptr,但有时强制转换很有用。在这种情况下使用演员表是可以的。 (答案已修复。无论如何谢谢:)
  • 如果你扣除一个函数的返回类型,并且在一个分支中有return nullptr,而在其他分支中有其他东西,除非你明确地转换nullptr,否则扣除将失败。
【解决方案2】:

我怀疑您对空指针nullptr之间的区别感到困惑,它们不一样。

这个函数返回nullptr

std::nullptr_t getNullPtr() { return nullptr; }

但返回是一件相当无用的事情,很少有充分的理由返回该类型的对象。

这个函数返回一个空指针:

A* getAPtr() { return nullptr; }

返回值是用nullptr初始化的,但它实际上是一个A*类型的空指针,而不是nullptr本身。

对于第一个函数,是的,您可以将返回的 std::nullptr_t 强制转换为另一种指针类型(您甚至不需要强制转换来进行转换,它会隐式发生)但这可能不是您想要的做。

对于第二个函数,您不需要强制转换它,因为它已经返回了正确的类型。

【讨论】:

  • 大概是因为getSomePtr() 没有返回A*
  • 正如我在回答中所说,从函数返回 nullptr_t 并不是很有用。
【解决方案3】:

只是对迄今为止给出的答案的补充,但稍微概括了您的问题(关于返回值的转换,请参阅其他答案):明确转换 nullptr 不仅有效,在某些情况下它甚至是不可避免的!例如,如果有多个重载函数,每个函数都接受不同的指针类型,您需要(无论出于何种原因)使用nullptr...调用其中一个函数...

void f(int*) { /*...*/ }
void f(double*) { /*...*/ }
void g()
{
    f(nullptr); // compilation error, ambiguous call!
    f(static_cast<int*>(nullptr)); // now compiler knows...
}

【讨论】:

    【解决方案4】:

    是的,您可以这样做。它仍然为空,因此调用访问其成员或数据是不安全的,但您可以在编译时询问有关其结构的问题。

    例如,这是&lt;cstddef&gt; 中的possible implementation of the offsetof(type, member) function,其中 nullptr 被强制转换为有效类型:

    #define offsetof(type,member) ((std::size_t) &((static_cast<type*>(nullptr))->member))
    

    【讨论】:

    • offsetof 与这个问题有什么关系?我不认为添加这可以澄清任何事情。
    • 最初的问题是“我可以将 nullptr 转换为另一种指针类型”。 offsetof 示例表明这是可以做到的,以及为什么在实践中可能会这样做。
    • 这是在构造一个type* 类型的右值对象,这完全是另一回事。在构造特定类型的右值指针时强制转换nullptr 是强制转换nullptr(不是空指针)的唯一合法原因。
    • 我不清楚你想表达什么观点。例如,您的争论是使用nullptr 而不是0,还是使用static_cast vs reinterpret_cast vs c-style cast?也许你可以改写你的答案。如果您能够提供一个示例来说明为什么此特定用例不合法,那将会很有帮助。
    猜你喜欢
    • 2011-08-04
    • 2016-07-26
    • 1970-01-01
    • 2021-03-18
    • 2013-01-10
    • 2021-09-20
    • 2022-08-17
    • 2016-03-01
    相关资源
    最近更新 更多