C ++代码在C ++ 03和C ++ 11中都是有效的,但是做不同的事情吗? [英] Can C++ code be valid in both C++03 and C++11 but do different things?
问题描述
C ++代码可以同时符合 C ++ 03 标准和 C ++ 11 标准,但根据正在编译的标准执行不同的操作?
答案是肯定的。在正面有:
- 以前隐式复制对象的代码现在会隐式移动它们。
在消极方面,标准附录C列出了几个例子。
字符串文字
#define u8abc
const char * s = u8def; //以前的abcdef,现在为def
和
b $ b
#define _xthere
hello_x //以前的hello there,现在是用户定义的字符串
类型转换0
++ 11,只有字面量是整数空指针常量:
void f(void *); //#1
void f(...); //#2
template< int N> void g(){
f(0 * N); // Calls#2;用于调用#1
}
整数除法和模
在C ++ 03中,允许编译器向0或负无穷大舍入。在C ++ 11中,必须向0舍入。
int i =(-1) //可能在C ++ 03中为-1,现在确保为0
嵌套模板关闭大括号之间的空格>> vs>>
在专业化或实例化内部,> c $ c>可能会被解释为C ++ 03中的右移。这更有可能打破现有的代码虽然:(从http://gustedt.wordpress.com/2013/12/15/a-disimprovement-observed-from-the-outside-right-angle-brackets/ )
template< unsigned len> unsigned int fun(unsigned int x);
typedef unsigned int(* fun_t)(unsigned int);
template< fun_t f> unsigned int fon(unsigned int x);
void total(void){
// fon< fun< 9> >(1)> 2在两个标准中
unsigned int A = fon<有趣的是, 9> >(1)>>(2)。
// fon< fun< 4> >(2)in C ++ 03
//编译时间错误C ++ 11
unsigned int B = fon<有趣的是, 9>(1)> >(2)。
}
运营商新
现在可以抛出除 std :: bad_alloc
之外的其他例外
struct foo {void * operator new(size_t x){throw std :: exception(); }}
try {
foo * f = new foo();
catch(std :: bad_alloc&){
// c ++ 03 code
} catch(std :: exception&){
// c ++ 11代码
}
用户声明的析构函数具有隐式异常规范
来自在C ++ 11中引入了什么重大变化的示例?
struct A {
〜A(){throwfoo; } //在C ++中调用std :: terminate 11
};
// ...
try {
A a;
} catch(...){
// C ++ 03将捕获异常
}
容器的size()
现在需要在O(1)中运行 b
$ b
std :: list< double>列表;
// ...
size_t s = list.size(); //可能是C ++中的O(n)操作03
std :: ios_base :: failure
不是从 std :: exception
派生的 b
希望它直接从 std :: exception
派生的代码可能会有不同的行为。
Is it possible for C++ code to conform to both the C++03 standard and the C++11 standard, but do different things depending on under which standard it is being compiled?
The answer is a definite yes. On the plus side there is:
- Code that previously implicitly copied objects will now implicitly move them when possible.
On the negative side, several examples are listed in the appendix C of the standard. Even though there are many more negative ones than positive, each one of them is much less likely to occur.
String literals
#define u8 "abc"
const char* s = u8"def"; // Previously "abcdef", now "def"
and
#define _x "there"
"hello "_x // Previously "hello there", now a user defined string literal
Type conversions of 0
In C++11, only literals are integer null pointer constants:
void f(void *); // #1
void f(...); // #2
template<int N> void g() {
f(0*N); // Calls #2; used to call #1
}
Rounded results after integer division and modulo
In C++03 the compiler was allowed to either round towards 0 or towards negative infinity. In C++11 it is mandatory to round towards 0
int i = (-1) / 2; // Might have been -1 in C++03, is now ensured to be 0
Whitespaces between nested template closing braces >> vs > >
Inside an specialization or instantiation the >>
might instead be interpreted as an right-shift in C++03. This is more likely to break existing code though: (from http://gustedt.wordpress.com/2013/12/15/a-disimprovement-observed-from-the-outside-right-angle-brackets/)
template< unsigned len > unsigned int fun(unsigned int x);
typedef unsigned int (*fun_t)(unsigned int);
template< fun_t f > unsigned int fon(unsigned int x);
void total(void) {
// fon<fun<9> >(1) >> 2 in both standards
unsigned int A = fon< fun< 9 > >(1) >>(2);
// fon<fun<4> >(2) in C++03
// Compile time error in C++11
unsigned int B = fon< fun< 9 >>(1) > >(2);
}
Operator new
may now throw other exceptions than std::bad_alloc
struct foo { void *operator new(size_t x){ throw std::exception(); } }
try {
foo *f = new foo();
catch (std::bad_alloc &) {
// c++03 code
} catch (std::exception &) {
// c++11 code
}
User-declared destructors have an implicit exception specification example from What breaking changes are introduced in C++11?
struct A {
~A() { throw "foo"; } // Calls std::terminate in C++11
};
//...
try {
A a;
} catch(...) {
// C++03 will catch the exception
}
size()
of containers is now required to run in O(1)
std::list<double> list;
// ...
size_t s = list.size(); // Might be an O(n) operation in C++03
std::ios_base::failure
does not derive from std::exception
anymore
Code that expects it to derive directly from std::exception
might behave differently.
这篇关于C ++代码在C ++ 03和C ++ 11中都是有效的,但是做不同的事情吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!