class 成员实例化期间:"no operator "[] 在使用 map[key] 访问 std::map 值时“匹配这些操作数”
During instantiation of class member: "no operator "[]" matches these operands" when accessing std::map value with map[key]
我关注这个已经有一段时间了。我不明白是什么在困扰它。给我问题的最少代码如下所示。我评论了发生错误的行。编译错误跟在代码之后。
#include <map>
#include <cstdlib>
#include <cstdint>
template<std::size_t D>
class myclassA{
private:
std::array<std::string, D> a;
std::map<std::string, std::size_t> a_type_num;
std::array<std::size_t, D> a_dims;
// used to initialize a_type_num
inline std::map<std::string, std::size_t> return_type_dims() const{
std::map<std::string, std::size_t> temp;
for(auto const &s: a)
temp.emplace(s, 0);
for(auto const &s: a)
temp[s]++;
return temp;
};
// used to initialize a_dims
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++)
temp[i] = a_type_num[a[i]]; // ERROR!!!
return temp;
};
public:
// constructor
myclassA(const std::array<std::string,D> &user) : a(user)
, a_type_num(return_type_dims())
, a_dims(return_site_dims())
{};
};
int main(int argc, char *argv[]){
myclassA<4> co({"d","d","p","p"});
return 0;
}
编译时出现错误:
src/main.cpp(32): error: no operator "[]" matches these operands
operand types are: const std::map<std::__cxx11::string, std::size_t, std::less<std::__cxx11::string>, std::allocator<std::pair<const std::__cxx11::string, std::size_t>>> [ const std::__cxx11::string ]
temp[i] = a_type_num[a[i]];
^
detected during:
instantiation of "std::array<std::size_t={unsigned long}, D> myclassA<D>::return_site_dims() const [with D=4UL]" at line 40
instantiation of "myclassA<D>::myclassA(const std::array<std::__cxx11::string, D> &) [with D=4UL]" at line 45
另一方面,像这样的东西编译得很好(我的意思是代码什么都不做,但它编译了):
#include <map>
#include <cstdlib>
#include <cstdint>
int main(int argc, char *argv[]){
// myclassA<4> co({"d","d","p","p"});
std::array<std::string, 10> a;
std::map<std::string, std::size_t> a_type_num;
std::array<std::size_t, 10> temp;
for(int i=0; i<10; i++)
temp[i] = a_type_num[a[i]];
return 0;
所以我的问题是:为什么它抱怨 no operator "[]" matches these operands
?
[]
运算符需要一个 std::map
而不是 const
,因为它在找不到键时的行为是通过插入键来修改映射。在您的代码中,您有 return_site_dims
方法,它是 const
方法,这意味着它只能 const
访问 myClassA
class,包括 a_type_num
地图。因此,此方法无法在该地图上使用 []
运算符。要解决此问题,您可以将 return_site_dims
设为非 const
方法。
return_site_dims()
被声明为 const
方法,因此它的 this
指针是 const myclassA*
,因此通过该指针访问的 a_type_num
成员是被视为 const std::map
对象。但是,std::map
没有可以在 const std::map
对象上调用的 operator[]
,因此出现编译器错误。如果找不到请求的键,映射的 operator[]
将插入一个新条目,并且它不能插入到 const std::map
对象中。
您可以改用地图的 at()
方法,它有一个 const
重载,不会插入丢失的键,而是抛出 std::out_of_range
异常:
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++)
temp[i] = a_type_num.at(a[i]); // <-- OK! exception if a[i] is not found...
return temp;
};
或者,您可以改用地图的 find()
方法:
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++) {
auto iter = a_type_num.find(a[i]);
if (iter != a_type_num.end())
temp[i] = iter->second;
else
temp[i] = ...; // <-- some default value of your choosing...
}
return temp;
};
它不能工作的原因是 return_site_dims
声明为 const
,但 operator[]
不是 const
方法(如果未找到元素)。如果您想要异常而不是手动处理,访问 const std::map
的唯一方法是使用 std::map::find
or std::map::at
。所以你的循环可以重写:
// used to initialize a_dims
std::array<std::size_t, D> return_site_dims() const {
std::array<std::size_t, D> temp;
decltype(a_type_num.end()) iter, iter_end = a_type_num.end();
for (int i=0; i<D; i++) {
iter = a_type_num.find(a[i]);
if (iter == iter_end) {
// HANDLE THIS SOMEHOW
}
temp[i] = *iter;
}
return temp;
}
旁注:您不需要声明 inline
函数 inline
,因为在 class 声明中编写的函数会自动如此。
我关注这个已经有一段时间了。我不明白是什么在困扰它。给我问题的最少代码如下所示。我评论了发生错误的行。编译错误跟在代码之后。
#include <map>
#include <cstdlib>
#include <cstdint>
template<std::size_t D>
class myclassA{
private:
std::array<std::string, D> a;
std::map<std::string, std::size_t> a_type_num;
std::array<std::size_t, D> a_dims;
// used to initialize a_type_num
inline std::map<std::string, std::size_t> return_type_dims() const{
std::map<std::string, std::size_t> temp;
for(auto const &s: a)
temp.emplace(s, 0);
for(auto const &s: a)
temp[s]++;
return temp;
};
// used to initialize a_dims
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++)
temp[i] = a_type_num[a[i]]; // ERROR!!!
return temp;
};
public:
// constructor
myclassA(const std::array<std::string,D> &user) : a(user)
, a_type_num(return_type_dims())
, a_dims(return_site_dims())
{};
};
int main(int argc, char *argv[]){
myclassA<4> co({"d","d","p","p"});
return 0;
}
编译时出现错误:
src/main.cpp(32): error: no operator "[]" matches these operands
operand types are: const std::map<std::__cxx11::string, std::size_t, std::less<std::__cxx11::string>, std::allocator<std::pair<const std::__cxx11::string, std::size_t>>> [ const std::__cxx11::string ]
temp[i] = a_type_num[a[i]];
^
detected during:
instantiation of "std::array<std::size_t={unsigned long}, D> myclassA<D>::return_site_dims() const [with D=4UL]" at line 40
instantiation of "myclassA<D>::myclassA(const std::array<std::__cxx11::string, D> &) [with D=4UL]" at line 45
另一方面,像这样的东西编译得很好(我的意思是代码什么都不做,但它编译了):
#include <map>
#include <cstdlib>
#include <cstdint>
int main(int argc, char *argv[]){
// myclassA<4> co({"d","d","p","p"});
std::array<std::string, 10> a;
std::map<std::string, std::size_t> a_type_num;
std::array<std::size_t, 10> temp;
for(int i=0; i<10; i++)
temp[i] = a_type_num[a[i]];
return 0;
所以我的问题是:为什么它抱怨 no operator "[]" matches these operands
?
[]
运算符需要一个 std::map
而不是 const
,因为它在找不到键时的行为是通过插入键来修改映射。在您的代码中,您有 return_site_dims
方法,它是 const
方法,这意味着它只能 const
访问 myClassA
class,包括 a_type_num
地图。因此,此方法无法在该地图上使用 []
运算符。要解决此问题,您可以将 return_site_dims
设为非 const
方法。
return_site_dims()
被声明为 const
方法,因此它的 this
指针是 const myclassA*
,因此通过该指针访问的 a_type_num
成员是被视为 const std::map
对象。但是,std::map
没有可以在 const std::map
对象上调用的 operator[]
,因此出现编译器错误。如果找不到请求的键,映射的 operator[]
将插入一个新条目,并且它不能插入到 const std::map
对象中。
您可以改用地图的 at()
方法,它有一个 const
重载,不会插入丢失的键,而是抛出 std::out_of_range
异常:
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++)
temp[i] = a_type_num.at(a[i]); // <-- OK! exception if a[i] is not found...
return temp;
};
或者,您可以改用地图的 find()
方法:
inline std::array<std::size_t, D> return_site_dims() const{
std::array<std::size_t, D> temp;
for(int i=0; i<D; i++) {
auto iter = a_type_num.find(a[i]);
if (iter != a_type_num.end())
temp[i] = iter->second;
else
temp[i] = ...; // <-- some default value of your choosing...
}
return temp;
};
它不能工作的原因是 return_site_dims
声明为 const
,但 operator[]
不是 const
方法(如果未找到元素)。如果您想要异常而不是手动处理,访问 const std::map
的唯一方法是使用 std::map::find
or std::map::at
。所以你的循环可以重写:
// used to initialize a_dims
std::array<std::size_t, D> return_site_dims() const {
std::array<std::size_t, D> temp;
decltype(a_type_num.end()) iter, iter_end = a_type_num.end();
for (int i=0; i<D; i++) {
iter = a_type_num.find(a[i]);
if (iter == iter_end) {
// HANDLE THIS SOMEHOW
}
temp[i] = *iter;
}
return temp;
}
旁注:您不需要声明 inline
函数 inline
,因为在 class 声明中编写的函数会自动如此。