std::for_each 参数 1 没有从 'std::pair<const point, int>' 到 'std::pair<point, int>&' 的已知转换
std::for_each no known conversion for argument 1 from 'std::pair<const point, int>' to 'std::pair<point, int>&'
我无法理解,因为这两种情况看起来很相似,首先 for_each 我无法获得 pair 的引用,其次我毫不费力地获得了 pair 的引用。谁能给我解释一下吗?
#include <unordered_map>
#include <cstring>
#include <algorithm>
#include <iostream>
struct table_info_t {
char name[32] = {0};
int posx;
int posy;
table_info_t(const char *name, int posx, int posy) : posx(posx), posy(posy) {
strncpy(this->name, name, 31);
}
};
struct point {
int posx;
int posy;
point(int posx, int posy) : posx(posx), posy(posy) { }
};
size_t hashstruct(const char* hptr, size_t size) {
size_t h = 31;
for (size_t i = 0; i < size; i++) {
h = (h + *hptr) * 31;
hptr++;
}
return h;
}
#define MAP_OPERATORS(typ)\
namespace std {\
\
template<>\
struct hash<typ> {\
std::size_t operator()(const typ &k) const { return hashstruct((const char*)&k, sizeof(typ)); }\
};\
\
bool operator==(const typ& one, const typ& other) { return memcmp(&one, &other, sizeof(typ)) == 0; }\
};
MAP_OPERATORS(point); //hash structure and operator==
MAP_OPERATORS(table_info_t); //hash structure and operator==
int main(int argc, char** argv) {
std::unordered_map<point, int> sp;
sp[point(3, 4)] = 7;
std::for_each(sp.begin(), sp.end(),
[](std::pair<point, int> pair) {
std::cout << pair.first.posx << "+" <<pair.first.posy << "=" << pair.second << "\n";
});
std::unordered_map<table_info_t, const char *> m;
m[table_info_t("make my day", 3, 14)] = "make my day 3,14";
std::for_each(m.begin(), m.end(),
[](std::pair<const table_info_t, const char * >& pair)
{
std::cout << pair.first.name << pair.first.posx << pair.first.posy << " " << pair.second << "\n";
}
);
return 0;
}
两种结构相差不大,但是在编译时,我得到这个错误:
In file included from .../4.8.2/include/c++/4.8.2/algorithm:62:0,
from .../src/main/c/hashtable.cpp:10:
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h: In instantiation of '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = std::__detail::_Node_iterator<std::pair<const point, int>, false, true>; _Funct = main(int, char**)::__lambda0]':
.../src/main/c/hashtable.cpp:45:24: required from here
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: error: no match for call to '(main(int, char**)::__lambda0) (std::pair<const point, int>&)'
__f(*__first);
^
.../src/main/c/hashtable.cpp:43:24: note: candidates are:
[](std::pair<point, int> &pair) {
^
In file included from .../4.8.2/include/c++/4.8.2/algorithm:62:0,
from .../src/main/c/hashtable.cpp:10:
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: note: void (*)(std::pair<point, int>&) <conversion>
__f(*__first);
^
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: note: candidate expects 2 arguments, 2 provided
.../src/main/c/hashtable.cpp:43:53: note: main(int, char**)::__lambda0
[](std::pair<point, int> &pair) {
^
.../src/main/c/hashtable.cpp:43:53: note: no known conversion for argument 1 from 'std::pair<const point, int>' to 'std::pair<point, int>&'
我需要删除引用。但是,对 pair 的引用对于第二个 for_each.
中的编译器来说完全没问题
当您遍历 std::unordered_map<Key, Value>
、
时
你迭代 std::pair<const KEY, VALUE>
第二种情况,你取std::pair<const KEY, VALUE>&
就可以了。
你甚至可以添加 const 因为你不改变对:const std::pair<const KEY, VALUE>&
.
在第一种情况下,您使用另一种类型std::pair<KEY, VALUE>&
。
std::pair<KEY, VALUE>
可以从 std::pair<const KEY, VALUE>
构造。但是,临时不能绑定到非常量左值引用。所以使用 std::pair<KEY, VALUE>&
是无效的。使用 std::pair<KEY, VALUE>
是有效的,但会产生额外的副本。有关详细信息,请参阅 unexpected copies with foreach over a map。
如果您可以访问 C++14,则可以使用通用 lambda 对其进行简化:
[](const auto& p) {
std::cout << p.first.posx << "+" << p.first.posy << "=" << p.second << "\n";
});
此外std::for_each
也可以用基于范围的for循环代替(即使在C++11中):
for(const auto& p : sp) {
std::cout << p.first.posx << "+" << p.first.posy << "=" << p.second << "\n";
};
我无法理解,因为这两种情况看起来很相似,首先 for_each 我无法获得 pair 的引用,其次我毫不费力地获得了 pair 的引用。谁能给我解释一下吗?
#include <unordered_map>
#include <cstring>
#include <algorithm>
#include <iostream>
struct table_info_t {
char name[32] = {0};
int posx;
int posy;
table_info_t(const char *name, int posx, int posy) : posx(posx), posy(posy) {
strncpy(this->name, name, 31);
}
};
struct point {
int posx;
int posy;
point(int posx, int posy) : posx(posx), posy(posy) { }
};
size_t hashstruct(const char* hptr, size_t size) {
size_t h = 31;
for (size_t i = 0; i < size; i++) {
h = (h + *hptr) * 31;
hptr++;
}
return h;
}
#define MAP_OPERATORS(typ)\
namespace std {\
\
template<>\
struct hash<typ> {\
std::size_t operator()(const typ &k) const { return hashstruct((const char*)&k, sizeof(typ)); }\
};\
\
bool operator==(const typ& one, const typ& other) { return memcmp(&one, &other, sizeof(typ)) == 0; }\
};
MAP_OPERATORS(point); //hash structure and operator==
MAP_OPERATORS(table_info_t); //hash structure and operator==
int main(int argc, char** argv) {
std::unordered_map<point, int> sp;
sp[point(3, 4)] = 7;
std::for_each(sp.begin(), sp.end(),
[](std::pair<point, int> pair) {
std::cout << pair.first.posx << "+" <<pair.first.posy << "=" << pair.second << "\n";
});
std::unordered_map<table_info_t, const char *> m;
m[table_info_t("make my day", 3, 14)] = "make my day 3,14";
std::for_each(m.begin(), m.end(),
[](std::pair<const table_info_t, const char * >& pair)
{
std::cout << pair.first.name << pair.first.posx << pair.first.posy << " " << pair.second << "\n";
}
);
return 0;
}
两种结构相差不大,但是在编译时,我得到这个错误:
In file included from .../4.8.2/include/c++/4.8.2/algorithm:62:0,
from .../src/main/c/hashtable.cpp:10:
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h: In instantiation of '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = std::__detail::_Node_iterator<std::pair<const point, int>, false, true>; _Funct = main(int, char**)::__lambda0]':
.../src/main/c/hashtable.cpp:45:24: required from here
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: error: no match for call to '(main(int, char**)::__lambda0) (std::pair<const point, int>&)'
__f(*__first);
^
.../src/main/c/hashtable.cpp:43:24: note: candidates are:
[](std::pair<point, int> &pair) {
^
In file included from .../4.8.2/include/c++/4.8.2/algorithm:62:0,
from .../src/main/c/hashtable.cpp:10:
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: note: void (*)(std::pair<point, int>&) <conversion>
__f(*__first);
^
.../4.8.2/include/c++/4.8.2/bits/stl_algo.h:4417:14: note: candidate expects 2 arguments, 2 provided
.../src/main/c/hashtable.cpp:43:53: note: main(int, char**)::__lambda0
[](std::pair<point, int> &pair) {
^
.../src/main/c/hashtable.cpp:43:53: note: no known conversion for argument 1 from 'std::pair<const point, int>' to 'std::pair<point, int>&'
我需要删除引用。但是,对 pair
当您遍历 std::unordered_map<Key, Value>
、
时
你迭代 std::pair<const KEY, VALUE>
第二种情况,你取std::pair<const KEY, VALUE>&
就可以了。
你甚至可以添加 const 因为你不改变对:const std::pair<const KEY, VALUE>&
.
在第一种情况下,您使用另一种类型std::pair<KEY, VALUE>&
。
std::pair<KEY, VALUE>
可以从 std::pair<const KEY, VALUE>
构造。但是,临时不能绑定到非常量左值引用。所以使用 std::pair<KEY, VALUE>&
是无效的。使用 std::pair<KEY, VALUE>
是有效的,但会产生额外的副本。有关详细信息,请参阅 unexpected copies with foreach over a map。
如果您可以访问 C++14,则可以使用通用 lambda 对其进行简化:
[](const auto& p) {
std::cout << p.first.posx << "+" << p.first.posy << "=" << p.second << "\n";
});
此外std::for_each
也可以用基于范围的for循环代替(即使在C++11中):
for(const auto& p : sp) {
std::cout << p.first.posx << "+" << p.first.posy << "=" << p.second << "\n";
};