【问题标题】:use of std::less in std::map does not compile在 std::map 中使用 std::less 无法编译
【发布时间】:2021-04-29 00:48:03
【问题描述】:

我无法理解为什么以下函数无法编译

#include <iostream>
#include <map>

int main(){
  std::map<int, int, std::less<int>> myMap(std::less<int>());
  myMap[2] = 2;
  std::cout << myMap[2] << std::endl;
  return 0;
}

报错信息如下-

std_less_check.cpp: In function ‘int main()’:
std_less_check.cpp:6:10: warning: pointer to a function used in arithmetic [-Wpointer-arith]
   myMap[2] = 2;
          ^
std_less_check.cpp:6:14: error: assignment of read-only location ‘*(myMap + 2)’
   myMap[2] = 2;
              ^
std_less_check.cpp:6:14: error: cannot convert ‘int’ to ‘std::map<int, int, std::less<int> >(std::less<int> (*)())’ in assignment
std_less_check.cpp:7:23: warning: pointer to a function used in arithmetic [-Wpointer-arith]
   std::cout << myMap[2] << std::endl;

虽然后续编译成功

#include <iostream>
#include <map>

int main(){
  std::map<int, int, std::less<int>> myMap(std::less<int>{});
  myMap[2] = 2;
  std::cout << myMap[2] << std::endl;
  return 0;
}

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 如何编译失败?实际的错误信息是什么?在构造std::less 对象时,使用(){} 应该没有区别。
  • @RemyLebeau 这就是我的想法。但似乎并非如此。我已经编辑了带有错误消息的问题。
  • 您是否有理由一开始就明确使用std::less?它已经是std::map 的默认比较器,因此您无需在此代码中显式使用它:std::map&lt;int, int&gt; myMap;
  • @RemyLebeau 我正在使用 std::less 来重现错误。在我的实际代码中,我使用的是自定义比较器。

标签: c++ c++11 constructor most-vexing-parse


【解决方案1】:

在第一个程序中,您有一个令人烦恼的解析。如果编译器可以将声明解析为变量或函数,它将选择将其解析为函数。

myMap 可以解析为函数声明。

它返回一个std::map&lt;int, int, std::less&lt;int&gt;&gt;

它接受std::less&lt;int&gt;() 类型的参数,它本身就是一个返回std::less&lt;int&gt; 并且不接受任何参数的函数类型。请注意,您实际上不能将函数类型作为参数;该类型实际上是一个指向不带参数并返回 std::less&lt;int&gt; 的函数的指针。


在第二个程序中,将() 替换为{} 可以解决歧义。现在myMap 不再是函数声明,而是声明了std::map&lt;int, int, std::less&lt;int&gt;&gt; 类型的变量。

【讨论】:

  • takes an argument of type std::less&lt;int&gt;() 请注意,该参数被调整为指向std::less&lt;int&gt;() 的指针,类似于如何将数组参数调整为指向此类数组元素的指针。
  • @eerorika 我不确定我是否跟随。参数是T()形式的函数类型吧?
  • 函数不是对象;没有函数类型的值。函数不能“按值传递”——就像数组不能“按值传递”一样。当您使用数组参数编写函数声明时,该参数被调整为指针(指向此类数组的元素)。当您编写带有函数参数的函数声明时,该参数被调整为指针(指向此类函数)。因此,即使您可以声明此类函数,也没有接受函数类型的函数或接受数组类型的函数。此类声明已调整
  • @atuly in C++, we can't declare functions within function. 你猜错了。在 C++ 中,我们可以在函数中声明函数。
  • @atuly 实际上,在 C++ 中,您不能在函数内部定义函数,但可以声明它。
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2021-03-17
相关资源
最近更新 更多