You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历C++ map触发实例化错误的原因排查

问题:遍历C++ map时触发拷贝构造函数错误

我定义了一个map<size_t, NGroup>用于按字符串长度分组,填充代码如下:

// 遍历字符串并按长度分组
map<size_t, NGroup> groups;
for (size_t i = 0; i < strs.size(); i++) {
    size_t len = strs[i].size();
    if (groups.count(len) != 0) {
        groups.at(len).appendString(strs[i]);
    } else {
        NGroup g(strs[i]);
        groups[len] = g;
    }
}

相关类定义:

class AnagramGroup {
public:
    map<char, size_t> freqs;
    map<char, size_t> ground;
    vector<string> anagrams;

    AnagramGroup(map<char, size_t> m, string anagram) {
        freqs = m;
        ground = m;
        anagrams.push_back(anagram);
    }
    AnagramGroup(AnagramGroup &other);
};

class NGroup {
public:
    vector<string> strings;
    vector<AnagramGroup> groups;

    NGroup(string str) {
        vector<string> strs = {str};
        strings = strs;
    }
    NGroup(vector<string> strs) {
        strings = strs;
    }
    NGroup(NGroup &other);

    void appendString(string str) {
        strings.push_back(str);
    }
};

尝试两种遍历方式:

map<size_t, NGroup>::iterator it;
for (it = groups.begin(); it != groups.end(); it++) {
...
}
for (const auto &p : groups) {
...
}

均触发相同错误:

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:13:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/cmath:1927:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/specfun.h:45:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algobase.h:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_pair.h:303:17: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be non-const
      constexpr pair(const pair&) = default;
                ^
Line 61: Char 38: note: in instantiation of template class 'std::pair<const unsigned long, NGroup>' requested here
        for (it = groups.begin(); it != groups.end(); it++) {
                                     ^

请问忽略了什么?


原因与解决方案

问题根源

错误核心在于自定义类的拷贝构造函数参数未使用const引用:

  • AnagramGroup和NGroup声明的拷贝构造函数,参数是非const的左值引用(AnagramGroup(AnagramGroup &other)、NGroup(NGroup &other))。
  • STL容器(如map)的元素是std::pair<const Key, Value>,当容器需要拷贝该pair时,会调用Value(即NGroup)的拷贝构造函数。但std::pair的默认拷贝构造函数接受const引用,而你的NGroup拷贝构造仅支持非const引用,导致类型不匹配,触发编译错误。

解决方案

修改两个类的拷贝构造函数,将参数改为const左值引用:

class AnagramGroup {
    // ... 其他成员
    AnagramGroup(const AnagramGroup &other);
};

class NGroup {
    // ... 其他成员
    NGroup(const NGroup &other);
};

若无需自定义拷贝逻辑,可直接让编译器生成默认的拷贝构造函数,更简洁:

class AnagramGroup {
    // ... 其他成员
    AnagramGroup(const AnagramGroup &other) = default;
};

class NGroup {
    // ... 其他成员
    NGroup(const NGroup &other) = default;
};

也可直接删除拷贝构造函数的声明,编译器会自动生成符合要求的默认版本。

额外优化建议

填充map时,groups[len] = g;会先默认构造NGroup再赋值,可改用emplace直接在容器内构造对象,避免不必要的拷贝:

groups.emplace(len, strs[i]);

内容的提问来源于stack exchange,提问作者joshua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:10:05