g++编译通过但clang++报错:返回右值引用绑定左值问题咨询
g与clang编译差异的标准符合性分析
问题核心
你的代码里,func4模板用decltype(auto)作为返回值类型,当传入std::move(mc)时出现了编译器行为分歧:
- 模板参数
T会被推导为MyClass,因此参数x的类型是MyClass&&(转发引用),但所有命名变量本质都是左值,所以x本身是一个左值。 decltype(auto)的推导规则是:如果返回的是变量名,返回类型直接等于decltype(变量名),这里就是MyClass&&(因为decltype(x)会保留变量的引用类型)。- 此时返回左值
x,相当于试图把左值绑定到右值引用类型的返回值,这违反了C++标准中“右值引用不能绑定到左值”的明确规则。
编译器行为判定
- clang的报错符合C标准:它严格执行了标准规定,拒绝了这种非法的返回操作。
- g++的编译通过属于非标准扩展:g在这里放宽了标准限制,允许左值绑定到右值引用返回类型,这是编译器自身的扩展特性,并不符合C标准要求。
代码修复方案
要让代码符合标准且在两种编译器下都正常运行,需要用std::move把左值x转换为右值,匹配右值引用的返回类型:
template<typename T> decltype(auto) func4(T&& x) { return std::move(x); }
内容的提问来源于stack exchange,提问作者unegare
相关产品推荐
相关产品推荐

