将临时对象强制转换为非常量引用时出错 [英] Error when casting temporary object to non-const reference

查看:62
本文介绍了将临时对象强制转换为非常量引用时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个可复制的示例,该示例取自有关使用临时的的问题stringstream对象

Here is a reproducible example taken from question about using temporary stringstream object:

#include <sstream>                     
#include <string>
#include <iostream>

using namespace std;

std::string transform(std::string);

int main()
{
    int i{};
    cout << transform( static_cast<stringstream &>(stringstream() << i).str() );
}

尝试使用 clang 9.0.0版进行编译在MacOS High Sierra下出现以下错误:

When trying to compile with clang version 9.0.0 under MacOS High Sierra I got following error:

$ clang++ -std=c++11 x.cc -c
x.cc:12:24: error: non-const lvalue reference to type 'basic_stringstream<...>' cannot bind to a temporary of type 'basic_stringstream<...>'
    cout << transform( static_cast<stringstream &>(stringstream() << i).str() );
                       ^                           ~~~~~~~~~~~~~~~~~~~
1 error generated.

在同一台计算机上(以及Linux上)使用g ++ 9.2.0时,一切都可以正常编译。

When g++ 9.2.0 is used on same machine (also on Linux) everything compiles fine.

似乎将转换从 stringstream& 转换为 const stringstream& stringstream&& 解决了问题。

Seems that changing cast from stringstream & to const stringstream & or to stringstream && solves problem.

问题是这是否是编译器错误也许clang对某些标准规则更严格?

The question is if this is compiler bug or maybe clang is more strict about some standard rules?

推荐答案

是的,我认为这是libc ++中的错误。

Yes, I think that is a bug in libc++.

根据 [ostream.rvalue] 有一个重载:

template<class charT, class traits, class T>
  basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&& os, const T& x);

但libc ++的实现类似于

template <class _Stream, class _Tp>
enable_if_t</*...*/, _Stream&&>
operator<<(_Stream&& __os, const _Tp& __x)
{
    // ...
}

该实现使此重载比
的类 operator<< 如果将流右值与<< 一起使用,则code> ostream 在重载解析中,而标准中的签名则不会be,并且在应该返回左值引用的情况下也返回右值引用。根据标准报价,它还返回与传递给它的类型相同的引用,同时应返回对其 ostream 基类的引用。

The implementation makes this overload a better candidate than the in-class operator<< of ostream in overload resolution if a stream rvalue is used with <<, while the signature in the standard wouldn't be, and it also returns a rvalue reference, when it should return a lvalue reference. It also returns a reference of same type as was passed to it, while it should return a reference to its ostream base class, according to the standard quote.

右值引用不能绑定到非常量左值引用,因此会出现错误。

The rvalue reference can not be bound to a non-const lvalue reference, hence the error.

该错误已被报告此处,关于行为此处,这似乎表明将来可能会对该标准进行调整,以强制执行libc ++的当前行为。

The bug has already been reported here and there is an open LWG issue regarding the behavior here, which seems to suggest that in the future the standard might be adjusted to mandate libc++'s current behavior.

这篇关于将临时对象强制转换为非常量引用时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆