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

为何GCC允许引用类型与值类型不匹配?如何阻止std::set转MySet

问题解答

问题1:为什么const MySet& a = get(0);未触发编译错误

这不是GCC的问题,完全符合C++标准规定的行为,原因如下:

  • get(0)返回一个std::set<int>类型的临时对象
  • 你的MySet类定义了接受const std::set<int>&的构造函数,且该构造函数未加explicit关键字,编译器会自动触发隐式转换,把std::set<int>临时对象转换成MySet临时对象
  • C++标准允许const左值引用绑定到临时对象,且这个临时对象的生命周期会被延长至引用的生命周期结束

另外你看到a.empty()返回true,是因为MySet的构造函数没有把传入的std::set<int>内容复制到基类(std::set<int>)中,基类部分是默认构造的空集合,所以调用empty()会返回true。

问题2:如何避免std::set隐式转换为MySet

只需要把MySet的构造函数声明为explicit即可。explicit关键字会禁止编译器自动进行隐式的构造函数调用,仅允许显式触发转换操作。

修改后的代码示例:

#include <bits/stdc++.h>

struct MySet : public std::set<int> {
  explicit MySet(const std::set<int>& s) {
      // 如果需要复制传入集合的内容,可添加:insert(s.begin(), s.end());
  }
};

std::set<int> get(int i) {
  return std::set<int>{i};
}

int main() {
  // 这条语句现在会触发编译错误,因为隐式转换已被禁止
  // const MySet& a = get(0);
  
  // 如需转换必须显式调用构造函数
  const MySet& a = MySet(get(0));
  std::cout << a.empty() << std::endl;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 20:43:50