我正在阅读cpp-next,其中提供了这个min
模板,作为如何将详细的C++代码与python代码进行比较的示例
template <class T, class U>
auto min(T x, U y)->decltype(x < y ? x : y)
{ return x < y ? x : y; }
Run Code Online (Sandbox Code Playgroud)
起初这看起来很无辜,但Daveed Vandevoorde做了这个话
在其返回类型规范中使用decltype的min模板不起作用:它返回一个引用(因为参数是一个左值),它最终引用了大多数常见用法中的局部变量.
我想每个人可能都不清楚这个问题是如何表现出来的.您能否详细解释一下并提供可能的解决方案?
即将推出的C++标准C++ 0x的一个很酷的新特性是"右值引用".右值引用类似于左值(正常)引用,但它可以绑定到临时值(通常,临时值只能绑定到const
引用):
void FunctionWithLValueRef(int& a) {...}
void FunctionWithRValueRef(int&& a) {...}
int main() {
FunctionWithLValueRef(5); // error, 5 is a temporary
FunctionWithRValueRef(5); // okay
}
Run Code Online (Sandbox Code Playgroud)
那么,为什么他们发明了一种全新的类型,而不仅仅是删除对普通引用的限制以允许它们绑定到临时版本?
为什么这不能编译?(克++ - 4.5)
template < typename U >
static void h () {
}
int main () {
auto p = &h<int>; // error: p has incomplete type
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个解决方法:
template < typename U >
static void h () {
}
int main () {
typedef decltype (&h<int>) D;
D p = &h<int>; // works
}
Run Code Online (Sandbox Code Playgroud) 给出以下场景,将其解释为C++ 0x代码:
struct B { };
struct A { B b; };
int main() {
B const& b = A().b;
/* is the object still alive here? */
}
Run Code Online (Sandbox Code Playgroud)
Clang和GCC(截至2011/02的行李箱版本)表现不同:Clang延长了使用寿命.GCC移动B
到新的临时对象,然后将引用绑定到该新临时对象.
我找不到任何一种行为都可以从标准的词汇中得出.表达式A().b
不是暂时的(见5.2.5).有人可以向我解释以下内容吗?
谢谢!
我正在阅读龙书,试图解决一个如下所述的练习
编写以下语言的常规定义:
- 所有数字串都没有重复的数字.提示:首先使用几位数来尝试此问题,例如{0,1,2}.
尽管试图解决它几个小时,我无法想象一个解决方案,除了极端罗嗦
d0 -> 0?
d1 -> 1?
d2 -> 2?
d3 -> 3?
d4 -> 4?
d5 -> 5?
d6 -> 6?
d7 -> 7?
d8 -> 8?
d9 -> 9?
d10 -> d0d1d2d3d4d5d6d7d8d9 | d0d1d2d3d4d5d6d7d9d8 | ...
Run Code Online (Sandbox Code Playgroud)
因此不得不写下10!
替代品d10
.既然我们将编写这个常规定义,我怀疑这是一个正确的解决方案.你能帮我吗?
这在理论上取决于任务吗?
它是否可以实际完成,并且生成的解析器是否可以使用足够的性能和输出(例如,LLVM IR或GCC的gimple)来集成到竞争编译器中?
我正在阅读n3290 C++ 11标准草案(尽可能接近实际标准文本),我注意到会i = i++ + 1;
产生未定义的行为.我以前见过类似的问题,但是它们是根据较旧的标准(序列点)来回答的.新标准在表达式和子表达式执行之间的关系之前/之后引入了Sequencing的概念.
1.9 13之前的序列是由单个线程(1.10)执行的评估之间的不对称,传递,成对关系,它在这些评估中引起部分顺序.给定任何两个评估A和B,如果A在B之前被排序,那么A的执行应该在B的执行之前.如果A在B之前没有排序,而B在A之前没有排序,那么A和B是未排序的.[注意:未经测试的评估的执行可能会重叠.-end note]评估A和B是不确定的顺序,当A在A之前测序或B在A之前测序,但未指定哪一个.[注意:不确定顺序的评估不能重叠,但可以先执行. - 尾注]
1.9 14在与要评估的下一个全表达式相关的每个值计算和副作用之前,对与全表达式相关的每个值计算和副作用进行排序.
1.9 15除非另有说明,否则对个体操作员的操作数和个别表达式的子表达式的评估是不确定的.[注意:在程序执行期间不止一次评估的表达式中,不需要在不同的评估中一致地执行对其子表达式的未序列和不确定顺序的评估.-end note]运算符操作数的值计算在运算符结果的值计算之前排序.如果对标量对象的副作用相对于对同一标量对象的其他影响或使用相同标量对象的值进行的值计算未进行排序,则行为未定义.
[ Example:
void f(int, int);
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // i becomes 9
i = i++ + 1; // the behavior is undefined
i = i + 1; // the value of i is incremented
f(i = -1, i = -1); // …
Run Code Online (Sandbox Code Playgroud) 一直在想,用[]或*声明变量之间的区别是什么?我看待它的方式:
char *str = new char[100];
char str2[] = "Hi world!";
Run Code Online (Sandbox Code Playgroud)
..应该是主要的区别,虽然我不确定你是否可以做类似的事情
char *str = "Hi all";
Run Code Online (Sandbox Code Playgroud)
..因为指针应该引用一个静态成员,我不知道它是否可以?
无论如何,真正困扰我的是知道以下两者之间的区别:
void upperCaseString(char *_str) {};
void upperCaseString(char _str[]) {};
Run Code Online (Sandbox Code Playgroud)
所以,如果有人能告诉我差异,我将不胜感激吗?我有一种预感,除了一些特殊情况外,两者都可以编译得相同吗?
泰
我正在阅读FDIS的这两段(12.2p {4,5}):
有两种情况,临时表在与完整表达结束时不同的地方被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素.如果构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,对默认参数中创建的每个临时的销毁进行排序.
和
第二个上下文是引用绑定到临时的.引用绑定的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生命周期内持续存在,除了:[...]
- 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止.
这两个似乎与以下案例相矛盾
struct A {
A() { std::cout << "C" << std::endl; }
~A() { std::cout << "D" << std::endl; }
};
struct B {
B(A const& a = A()) { }
};
typedef B array[2];
int main() {
array{};
}
Run Code Online (Sandbox Code Playgroud)
这个输出是否会CDCD
按照第一个上下文的要求输出,还是CCDD
按照第二个上下文的要求输出?GCC似乎遵循第二个上下文描述和输出CCDD
.我忽略了一些重要的事情吗?
编辑:我不认为它需要C++ 0x.new
我的问题也影响了这个表达式:
new array(); /* CDCD or CCDD ?? */
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,GCC遵循第一个上下文和输出CDCD
.
我试图在另一个函数的尾随返回类型中重用运算符的返回类型,但不幸的是clang不接受它
struct A {
int operator[](int);
auto at(int i) -> decltype((*this)[i]);
};
Run Code Online (Sandbox Code Playgroud)
Clang说我班上没有算子[].Gcc确实接受了我的代码.我的代码真的无效吗?
c++ language-lawyer operator-keyword c++11 trailing-return-type