Stack Overflow教给我的很多东西都是所谓的"最令人烦恼的解析",经典地用一条线来证明
A a(B()); //declares a function
Run Code Online (Sandbox Code Playgroud)
虽然这对于大多数人而言,直观地看起来是a类型对象的声明A,将临时B对象作为构造函数参数,它实际上是一个函数a返回的声明A,将一个指针指向一个返回的函数,它B本身不带参数.同样的线
A a(); //declares a function
Run Code Online (Sandbox Code Playgroud)
也属于同一类别,因为它代替一个对象,它声明了一个函数.现在,在第一种情况下,这个问题的通常解决方法是在其周围添加一组额外的括号/括号B(),因为编译器会将其解释为对象的声明
A a((B())); //declares an object
Run Code Online (Sandbox Code Playgroud)
但是,在第二种情况下,执行相同操作会导致编译错误
A a(()); //compile error
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么?是的我非常清楚正确的"解决方法"是将其更改为A a;,但我很想知道()第一个示例中的额外功能是什么,然后在重新应用它时不起作用第二个例子.A a((B()));变通办法是否是写入标准的特定异常?
在Qt中,有一个foreach使用宏(Q_FOREACH)实现的循环.根据编译器的不同,有不同的实现.
海湾合作委员会的定义如下:
#define Q_FOREACH(variable, container) \
for (QForeachContainer<__typeof__(container)> _container_(container); \
!_container_.brk && _container_.i != _container_.e; \
__extension__ ({ ++_container_.brk; ++_container_.i; })) \
for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))
Run Code Online (Sandbox Code Playgroud)
...使用QForeachContainer如下定义的辅助类:
template <typename T>
class QForeachContainer {
public:
inline QForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
const T c;
int brk;
typename T::const_iterator i, e;
};
Run Code Online (Sandbox Code Playgroud)
在容器Q_FOREACH宏必须是一类T至少必须提供T::const_iterator类型,T.begin()和一个T.end()方法,像所有的STL容器以及最Qt的容器,如QList,QVector, …
可能重复:
C++:临时参数的生命周期?
据说临时变量作为评估完整表达式的最后一步被破坏,例如
bar( foo().c_str() );
Run Code Online (Sandbox Code Playgroud)
临时指针一直存在,直到bar返回,但是为什么
baz( bar( foo().c_str() ) );
Run Code Online (Sandbox Code Playgroud)
是否它仍然存在直到bar返回,或者baz返回意味着完全表达结束在这里,编译器我检查了baz返回后的destruct对象,但我可以依赖它吗?
这与昨天发布的问题有关.
class A
{
public:
mutable int x;
A()
{
static int i = 0;
x = i;
i++;
std::cout << " A()" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
void foo() const
{
x = 1;
};
};
class B
{
public:
const A & a;
B(const A & a) : a(a)
{
std::cout << " B()" << std::endl;
}
~B()
{
std::cout << "~B()" << std::endl;
}
void doSomething()
{
a.foo();
}; …Run Code Online (Sandbox Code Playgroud) 我遇到了以下代码段
std::string&& test()
{
std::string m="Hello";
return (std::move(m));
}
int main()
{
std::string&& m = test();
}
Run Code Online (Sandbox Code Playgroud)
我理解上面的代码不正确且不安全,但我不确定原因.到目前为止,这是我对代码的理解.在功能test
在堆栈上创建一个std::string调用的局部变量m.
然后返回此字符串,但不是复制,而是将其内容移动到临时字符串.此时函数test结束调用变量的析构函数m(其内容被移动到temp)
临时值现在绑定到右值引用m.根据我的理解,一个临时的将保持活着,直到它的绑定对象存在并且在范围内.
有人可以告诉我哪里可能出错了吗?为什么上面的代码不安全?
我不太明白为什么func下面代码中的第二次调用不起作用:
#include <string>\n#include <iostream>\n#include <tuple>\n\nusing Tuple = std::tuple<const int&, const std::string&>;\n\nvoid func(const Tuple& t)\n{\n std::cout << std::get<1u>(t) << std::endl;\n}\n\nint main()\n{\n const int n = 3;\n const std::string text = "xyz";\n \n func(Tuple(n, text));\n\n //Does not work:\n //func(Tuple(5, "abc"));\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n临时字符串什么时候"abc"销毁?
编辑1
\n所以,最后,根据 \xe5\xba\xb7\xe6\xa1\x93\xe7\x91\x8b 这是有效的:
\n func(Tuple(5, std::string("abc")));\nRun Code Online (Sandbox Code Playgroud)\n但这并没有:
\n Tuple t(5, std::string("abc"));\n func(t);\nRun Code Online (Sandbox Code Playgroud)\n正确的?如果是的话有什么区别?
\n如果自动绑定到lambda函数,自动生命的生命是否延伸到lambda函数的生命周期?
最简单的情况:
auto genfunc (int start)
{
int count=start;
return [&count] {
return count++;
};
}
Run Code Online (Sandbox Code Playgroud)
这是好的还是未定义的行为?