我们都知道这样的事情在c ++中是有效的:
const T &x = T();
Run Code Online (Sandbox Code Playgroud)
而:
T &x = T();
Run Code Online (Sandbox Code Playgroud)
不是.
在最近的一个问题中,谈话导致了这一规则.OP发布了一些明显唤起UB的代码.但我希望它的修改版本能够工作(这是修改后的版本):
#include <iostream>
using namespace std;
class A {
public:
A(int k) { _k = k; };
int get() const { return _k; };
int _k;
};
class B {
public:
B(const A& a) : _a(a) {}
void b() { cout << _a.get(); }
const A& _a;
};
B* f() {
return new B(A(10));
}
int main() {
f()->b();
}
Run Code Online (Sandbox Code Playgroud)
这会在某些机器上打印垃圾,在其他机器上打印10个......对我来说听起来像UB :-).但后来我想,A …
假设我有一个跨平台Path类,如:
class Path {
public:
// ...
Path parent() const; // e.g., /foo/bar -> /foo
std::string const& as_utf8() const {
return path;
}
private:
std::string path;
};
Run Code Online (Sandbox Code Playgroud)
所述parent()成员函数返回的父路径this的路径,所以它(正确)返回一个新构造的Path对象,它表示它.
对于将OS级别的路径表示为UTF-8字符串(例如,Unix)的平台,将as_utf8()引用直接返回到内部表示似乎是合理的,path因为它已经是 UTF-8.
如果我有以下代码:
std::string const &s = my_path.as_utf8(); // OK (as long as my_path exists)
// ...
Path const &parent = my_path.parent(); // OK (temporary lifetime extended)
Run Code Online (Sandbox Code Playgroud)
这两行都很好,因为:
my_path持续存在,那么s仍然有效.parent()由const&.到现在为止还挺好.但是,如果我有以下代码: …
我遇到了这个问题format!,据我所知,在一个没有锚定到任何东西的模式中创建一个临时值。
let x = 42;
let category = match x {
0...9 => "Between 0 and 9",
number @ 10 => format!("It's a {}!", number).as_str(),
_ if x < 0 => "Negative",
_ => "Something else",
};
println!("{}", category);
Run Code Online (Sandbox Code Playgroud)
在这段代码中, 的类型category是 a &str,它通过返回一个像 的文字来满足"Between 0 and 9"。如果我想使用 将匹配的值格式化为切片as_str(),则会出现错误:
let x = 42;
let category = match x {
0...9 => "Between 0 and 9",
number @ 10 => format!("It's a {}!", …Run Code Online (Sandbox Code Playgroud) 这可能是我不理解借用检查器的一些技术细节的教科书案例,但如果有人能帮我解决这个问题会很好。
我有这个(令人难以置信的简化)代码块,它编译得非常好。
pub struct Example(pub Vec<String>);
impl Example {
pub fn iter(&self) -> impl Iterator<Item=&String> {
self.0.iter()
}
}
pub fn some_condition(_: &str) -> bool {
// This is not important.
return false;
}
pub fn foo() -> bool {
let example = Example(vec!("foo".to_owned(), "bar".to_owned()));
let mut tmp = example.iter();
tmp.all(|x| some_condition(x))
}
pub fn main() {
println!("{}", foo());
}
Run Code Online (Sandbox Code Playgroud)
但是,我尝试的第一件事(在我看来,应该等同于上述内容)是tmp完全删除临时变量,如下所示
pub fn foo() -> bool {
let example = Example(vec!("foo".to_owned(), "bar".to_owned()));
example.iter().all(|x| some_condition(x))
}
Run Code Online (Sandbox Code Playgroud)
但是这个版本会产生以下错误。
pub struct …Run Code Online (Sandbox Code Playgroud) 多年前我相信C与C++相比绝对纯净,因为编译器无法生成任何你无法预测的代码.我现在相信反例包括volatile关键字和内存障碍(在多处理器编程或内存映射硬件设备的设备驱动程序中,其中普通汇编语言甚至比C编译器的优化更纯粹).
目前我正在尝试枚举C++编译器可以执行的不可预测的事情.关于C++的主要抱怨是编译器将隐式实例化临时对象,但我相信这些情况都可以预期.我正在考虑的案例是:
explicit关键字operator ()还有其他人吗?
看看这段代码片段
struct S{ int i; int j;};
int main()
{
assert(S().i == S().j) // is it guaranteed ?
}
Run Code Online (Sandbox Code Playgroud)
为什么?
请考虑以下代码:
class A {
A(const A&);
public:
A() {}
};
int main() {
const A &a = A();
}
Run Code Online (Sandbox Code Playgroud)
此代码与GCC 4.7.2编译良好,但无法使用Visual C++ 2010进行编译,并出现以下错误:
test.cc(8) : error C2248: 'A::A' : cannot access private member declared in class 'A'
test.cc(2) : see declaration of 'A::A'
test.cc(1) : see declaration of 'A'
Run Code Online (Sandbox Code Playgroud)
因此,在将临时绑定到引用时,是否有必要使用复制构造函数?
这与我之前的问题有些相关:
#include<iostream>
using namespace std;
int fun(int &x)
{
return x;
}
int main()
{
cout << fun(10);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释错误的原因吗?
谢谢
我需要使用execute命令将select语句中的数据插入临时表.
if OBJECT_ID('tempdb..#x') is not null
drop table #x
Create Table #x(aaa nvarchar(max))
declare @query2 nvarchar(max)
set @query2 = 'SELECT [aaa] from IMP_TEMP'
INSERT #x
SELECT [aaa] from IMP_TEMP -- THIS WORKS
SELECT *from #x
INSERT #x
exec @query2 -- THIS DOES NOT WORKS, WHY?
SELECT *from #x
Run Code Online (Sandbox Code Playgroud) 背景:
让我们说我有这样的事情:
struct item
{
int x;
item(int y): x(y) {}
}
class item_view
{
const item& it;
public:
item_view(const item& it_) : it(it_) {}
friend std::ostream& operator<<(std::ostream& os, const item_view& view)
{return os;} //actually is more complicated
}
Run Code Online (Sandbox Code Playgroud)
我不能只重载的原因operator<<是它更人性化,并且视图用于将数据传递给SQL,因此必须转义滴答和其他一些字符.
问题:
有人可能想做这样的事情:
auto view = item_view(2);
std::cout << view;
Run Code Online (Sandbox Code Playgroud)
这似乎是未定义的行为.
题:
如何防止item_view临时建筑?