Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指针映射中的默认值nullptr是否已定义?_C++_C++11_Big O_Time Complexity - Fatal编程技术网

C++ 指针映射中的默认值nullptr是否已定义?

C++ 指针映射中的默认值nullptr是否已定义?,c++,c++11,big-o,time-complexity,C++,C++11,Big O,Time Complexity,下面的代码似乎总是遵循真正的分支 #include <map> #include <iostream> class TestClass { // implementation } int main() { std::map<int, TestClass*> TestMap; if (TestMap[203] == nullptr) { std::cout << "true"; } else { std::cou

下面的代码似乎总是遵循真正的分支

#include <map>
#include <iostream>

class TestClass {
  // implementation 
}

int main() {
  std::map<int, TestClass*> TestMap;
  if (TestMap[203] == nullptr) {
    std::cout << "true";
  } else {
    std::cout << "false";
  }
  return 0;
}

一种解决方案是,在检查
地图时,使用特殊函数提供默认值。然而,我的理解是,这将导致查找的复杂性为
O(n)
,而不是
O(1)
。在我的场景中,这并不是一个太大的问题(只有少数日志),但更好的解决方案是强制
Log*
类型的指针在默认情况下引用
nullptr
,从而使查找检查
O(1)
同时可移植。这可能吗?如果可能,我将如何做?

映射值总是初始化其成员(当然,在没有复制初始化的情况下),而内置类型的值初始化意味着零初始化,因此它确实是定义的行为。这对于使用
操作符[]
访问元素时生成的新键的值部分尤其如此,调用该操作符之前不存在该元素

但是请注意,未序列化的指针不一定是空指针;事实上,仅仅读取它的值就已经调用了未定义的行为(在某些情况下,在某些平台上可能会出现分段错误)。关键是映射中的指针不是未初始化的。所以如果你写一个例子

void foo()
{
  TestClass* p;
  // ...
}
p
将不会初始化为
nullptr

但是请注意,您可能希望检查是否存在,以避免累积不必要的条目。您可以使用
find
成员函数检查是否存在:

map<int, TestClass*>::iterator it = TestMap.find(203);
if (it == map.end())
{
  // there's no such element in the map
}
else
{
  TestClass* p = it->second;
  // ...
}
迭代器it=TestMap.find(203); if(it==map.end()) { //地图上没有这样的元素 } 其他的 { TestClass*p=it->second; // ... }
是的,这是定义的行为。如果当您通过
操作符[]
访问某个元素时,该元素尚未出现在地图中,那么它将被默认构造。

感谢您的快速回答!为了进一步澄清,是否将“TestClass*p();”初始化为nullptr?@MrBushido No.
TestClass*p()
不声明变量,它声明一个不带参数的函数,并返回
TestClass*
.MrBushido:
int*p默认已初始化,因此具有不确定的值<代码>int*p{}
初始化为零,并且转换为指针的0始终是空指针常量,因此将与nullptr进行比较。答案是使用了错误的术语。如果
操作符[]
中的新元素不存在,则
std::map
将对其进行值初始化(而不是默认初始化)。请务必注意这一差异,因为POD类型的默认初始化使它们未初始化,而值初始化意味着相同类型的零初始化。在答案中出现默认初始化的地方替换值初始化将使其正确。相信我,我刚刚检查了这两个标准。在C++03中,
T()
的描述在5.2.3p2中,表达式T(),其中T是非数组完整对象类型或(可能是cv限定的)void类型的简单类型说明符(7.1.5.2),创建指定类型的右值,该值初始化为*。C++11中的同一个引号读取*表达式T(),其中T是非数组完整对象类型或(可能是cv限定的)void类型的简单类型说明符或typename说明符,它创建指定类型的prvalue,该值已初始化
map<int, TestClass*>::iterator it = TestMap.find(203);
if (it == map.end())
{
  // there's no such element in the map
}
else
{
  TestClass* p = it->second;
  // ...
}