我最近遇到了一个问题stringstream,因为我错误地认为std::setw()这会影响每次插入的字符串流,直到我明确地更改它.但是,插入后总是未设置.
// With timestruct with value of 'Oct 7 9:04 AM'
std::stringstream ss;
ss.fill('0'); ss.setf(ios::right, ios::adjustfield);
ss << setw(2) << timestruct.tm_mday;
ss << timestruct.tm_hour;
ss << timestruct.tm_min;
std::string filingTime = ss.str(); // BAD: '0794'
Run Code Online (Sandbox Code Playgroud)
所以,我有很多问题:
setw()这样?std::ios_base::width()和std::setw()?下面这行是什么意思?为什么允许这样做,因为 0 是右值而不是变量名?const这句话的意义何在?
const int &x = 0;
Run Code Online (Sandbox Code Playgroud) C++只允许将临时对象分配给const引用.它不允许分配临时对象来引用.
例如:
String& a = String("test"); // Error
const String& a = String("test"); // Ok
Run Code Online (Sandbox Code Playgroud)
无论我到哪里谷歌这个结果,我只看到以下答案
有人说,临时对象在声明后消失了.所以你不应该修改它.
如果C++,如此热衷于阻止修改临时对象,它应该阻止读取临时对象吗?如果临时对象消失了,那么从那里读取内容是没有意义的吗?权利可能发生的可能情况也可能涉及阅读.
那为什么它一直阻止写入并允许读取?
请给我一个可靠的c ++代码说明.
请不要通过指出一些替代方案来偏离问题.请给我一个可靠的答案代码,为什么const int&被允许,而int&不允许用于临时对象.
一个说&&在那里..我的问题不同..另一个说,改变不会反映..改变也不会反映即使它也是const int&.例如:双倍; Const int&i = a; 一个++; 不会影响我..
我明白,当我们定义类的类复制构造函数时,必须作为三个状态的规则.我还注意到复制构造函数的参数通常const如下面的代码所示:
class ABC {
public:
int a;
int b;
ABC(const ABC &other)
{
a = other.a;
b = other.b;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如果复制构造函数的参数不是const会发生什么:
class ABC
{
public:
int a;
int b;
ABC(ABC &other)
{
a = other.a;
b = other.b;
}
}
Run Code Online (Sandbox Code Playgroud)
我理解在某些情况下,如果复制构造函数的参数是const,那么第二个实现将失败.此外,如果复制构造函数的参数是const,则要复制的对象在此过程中不会更改其内容.但是,我注意到有些人仍然使用第二个实现而不是第一个实现.是否有任何理由认为第二种实施方式是首选的?
这是一个非常小的例子:
class Foo
{
public:
Foo(int x) {};
};
void ProcessFoo(Foo& foo)
{
}
int main()
{
ProcessFoo(Foo(42));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以上编译在Visual Studio上很好,但在Linux和Mac上生成错误.
编译上面会生成这个:
$ g++ -std=c++11 -c newfile.cpp
newfile.cpp: In function ‘int main()’:
newfile.cpp:23:23: error: invalid initialization of non-const reference of type ‘Foo&’ from an rvalue of type ‘Foo’
ProcessFoo(Foo(42));
^
newfile.cpp:14:6: note: in passing argument 1 of ‘void ProcessFoo(Foo&)’
void ProcessFoo(Foo& foo)
Run Code Online (Sandbox Code Playgroud)
我找到了三个解决方法:
像这样:
Foo foo42(42);
ProcessFoo(foo42);
Run Code Online (Sandbox Code Playgroud)
ProcessFoo采用const引用: void ProcessFoo(const Foo& foo)
ProcessFoo只是让Foo按值传递. void ProcessFoo(Foo foo)
为什么编译器禁止我的原始代码?(这是什么防守)?上面三个满足编译器的解决方法中的每一个都有什么用?MSVC会允许什么,但不是g …
为什么C++委员会决定const引用应该延长temporaries的生命周期?
这个事实已经在网上广泛讨论过,包括stackoverflow.解释这种情况的最终资源可能就是GoTW:
这种语言功能的基本原理是什么?它知道了吗?
(另一种选择是临时的寿命不会被任何参考文献扩展.)
我自己的宠物理论的基本原理是这种行为允许对象隐藏实现细节.使用此规则,成员函数可以在不对客户端代码进行任何更改的情况下,在返回值或const引用与已内部存在的值之间切换.例如,矩阵类可能能够返回行向量和列向量.为了最小化副本,可以返回一个或另一个作为参考,具体取决于实现(行主要与列主要).无论通过引用返回哪一个都必须通过复制并返回该值来返回(如果返回的向量是连续的).库编写者可能希望在未来改变实现(行主要与列专业),并防止客户端编写强烈依赖于实现是行主要还是列主要的代码.通过要求客户端接受返回值为const ref,矩阵类可以返回const引用或值,而无需对客户端代码进行任何更改.无论如何,如果原始的理由是已知的,我想知道它.
使用此代码:
int main()
{
try
{
throw -1;
}
catch (int& x)
{
std::cerr << "We caught an int exception with value: " << x << std::endl;
}
std::cout << "Continuing on our merry way." << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们有:
/tmp$ ./prorgam.out
Continuing on our merry way
We caught an int exception with value: -1
Run Code Online (Sandbox Code Playgroud)
catch块如何读取-1为int&?我们无法为非常量左值引用赋值。
为什么第二条std::cout语句在第一条std::cerr语句之前执行?
移动语义的想法是,您可以从另一个临时对象(由右值引用引用)中获取所有内容,并将"所有内容"存储在对象中.这有助于避免在单个构造事物足够的情况下进行深度复制 - 因此您可以在rvalue对象中构造事物,然后将其移动到长寿命对象中.
为什么C++不允许将左值对象绑定到右值引用?两者都允许我更改引用的对象,因此在访问引用对象的内部方面对我没有任何区别.
我能猜到的唯一原因是函数重载模糊问题.
在Visual Studio 2012RC中,有一些非标准扩展.例如,此代码编译:
#include <string>
using namespace std;
void value(string& value)
{
value = "some";
}
int main()
{
value(string("nice"));
}
Run Code Online (Sandbox Code Playgroud)
并警告它是非标准扩展名.所以,我想了解它是如何实现的以及代码如何转换(使用const_cast进行rvalue-reference或const引用)?
从我读过和看过的内容来看,你不能将一个rvalue的表达式绑定到左值引用.然而,我所看到的是你可以将rvalue绑定到rvalue引用,并且由于命名的rvalue引用本质上是一个左值,你可以将它绑定到左值引用.禁止将右值绑定到左值引用的原因是什么.它是出于优化目的吗?
举个例子:
#include <iostream>
using std::cout;
void bar ( int& b ) {
cout << "bar " << b << "\n";
b = 3;
}
void foo ( int&& a ) {
cout << a << "\n";
bar(a);
cout << a << "\n";
}
int main ( int argc, char ** argv ) {
foo(1);
}
Run Code Online (Sandbox Code Playgroud)