C ++代码在C ++ 03和C ++ 11中都是有效的,但是做不同的事情吗? [英] Can C++ code be valid in both C++03 and C++11 but do different things?

查看:120
本文介绍了C ++代码在C ++ 03和C ++ 11中都是有效的,但是做不同的事情吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆