为何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
相关产品推荐
相关产品推荐

