C++ 在C++;11?

C++ 在C++;11?,c++,c++11,C++,C++11,我知道C++11中至少有一个更改会导致一些旧代码停止编译:在标准库中引入显式运算符bool(),替换运算符void*()的旧实例。诚然,这将破坏的代码可能是一开始就不应该有效的代码,但它仍然是一个破坏性的变化:以前有效的程序不再有效 是否还有其他中断更改?显式转换运算符的引入是如何中断更改的?旧版本仍然和以前一样“有效” 是的,从运算符void*()const到显式运算符bool()const的更改将是一个突破性的更改,但前提是其使用方式本身是错误的。一致性代码不会被破坏 现在,另一个突破性的变

我知道C++11中至少有一个更改会导致一些旧代码停止编译:在标准库中引入
显式运算符bool()
,替换
运算符void*()
的旧实例。诚然,这将破坏的代码可能是一开始就不应该有效的代码,但它仍然是一个破坏性的变化:以前有效的程序不再有效

是否还有其他中断更改?

显式转换运算符的引入是如何中断更改的?旧版本仍然和以前一样“有效”


是的,从
运算符void*()const
显式运算符bool()const
的更改将是一个突破性的更改,但前提是其使用方式本身是错误的。一致性代码不会被破坏

现在,另一个突破性的变化是:


编辑:请记住(参见注释)。这是一个方便的结构,可以使类型相互依赖。由于struct实际上做的不多,因此应该修复它:

template<class T>
struct identity{
  typedef T type;
};
模板
结构标识{
T型;
};
打破改变


首先,如果您使用
decltype
constepr
nullptr
等作为标识符,那么您可能会遇到麻烦……

自动关键字的含义已更改

struct x {
   x(int) {}
};

void f(auto x = 3) { }

int main() {
   f();
}
C++03:有效


C++0x:
错误:参数声明为“auto”
关于

()


如果你仔细阅读注释,隐式移动返回也是一个突破性的改变。

容器库有许多改变,允许更高效的代码,但在一些特殊情况下会悄悄地破坏向后兼容性


考虑,例如:

< P>有一个不兼容的部分,在附录<代码> C.2<代码>“C++和ISO C++ 2003”。 总结,在此解释FDI,使其(更好)适合作为SO答案。我添加了一些我自己的例子来说明差异

有一些与库相关的不兼容,我并不确切知道其含义,因此我将这些留给其他人详细阐述

核心语言


新关键字:alignas、alignof、char16\u t、char32\u t、constexpr、decltype、noexcept、nullptr、static\u assert和thread\u local


某些大于long表示的整数文字可能会从无符号整数类型更改为有符号long


使用整数除法的有效C++ 2003代码将结果向着0或负无穷大旋转,而C++ 0x总是将结果舍入0。 (无可否认,对大多数人来说,这并不是一个真正的兼容性问题)


使用C++关键字2003作为代码的存储类说明符,在C++ 0x.</P>中无效。


缩小转换范围会导致与C++03不兼容。例如,下面的代码在C++ 2003中是有效的,但在国际标准中无效,因为double to int是一个缩小转换:


当隐式定义格式错误时,隐式声明的特殊成员函数定义为删除

一个有效的C++ 2003程序,在不需要定义的上下文中使用这些特殊成员函数之一(例如,在未被评估的表达式中)变得不正确。

我举的例子:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }
static void f(int) { }
void f(long) { }

template<typename T>
void g(T t) { f(t); }

int main() { g(0); }
一些SFINAE已经使用了这种规模的技巧,现在需要更改:)


用户声明的析构函数具有隐式异常规范

我举的例子:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }
static void f(int) { }
void f(long) { }

template<typename T>
void g(T t) { f(t); }

int main() { g(0); }
此代码在C++0x中调用
terminate
,但在C++03中不调用。因为C++0x中
A::~A
的隐式异常规范是
noexcept(true)


<> >包含C++ > 2003的有效C++声明在C++ 0x中不正确地形成。

一个包含<代码> >代码>的有效C++ 2003表达式,紧接着另一个<代码> >代码>现在可以被当作关闭两个模板。

在C++03中,
>
始终是移位运算符标记



允许对具有内部链接的函数进行依赖调用

我举的例子:

struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }
static void f(int) { }
void f(long) { }

template<typename T>
void g(T t) { f(t); }

int main() { g(0); }
不采用更好的匹配
f(A)
,因为它没有外部链接


图书馆的变化

使用C++标准添加的任何标识符的有效C++ 2003代码 在本国际标准中,C++0x库可能无法编译或产生不同的结果


< C++ > C++代码2003,包含新的C++0x标准库头的名称,在本国际标准中无效。

已编译为Exchange的代码C++在<代码> <代码>中可能必须包括“代码> <代码> < /P>


全局名称空间
posix
现在保留用于标准化


<有效的C++ 2003代码,定义了代码>重写< /代码>,<代码>最终<代码> >代码>载波依赖>代码>,或代码> NordeURN <代码>,因为宏在C++ 0x.</P>中无效。
不兼容部分未涵盖的一些核心不兼容:


如果名称作为参数传递给模板参数,则C++0x将注入的类名视为模板;如果名称作为类型传递给模板类型参数,则将其视为类型

如果在这些场景中,有效的C++03代码依赖于注入的类名始终是一个类型,那么它的行为可能会有所不同。示例代码

此调用
A::f
的有效C++03代码在C++0x中无效,因为实例化时的名称查找将找到
A::f
,而不是
B::f
,从而导致与at定义查找冲突

目前还不清楚这是否是FDI的缺陷。委员会意识到
struct B { void f(); };

template<typename T>
struct A : virtual B { void f(); };

template<typename T>
struct C : virtual B, A<T> {
  void g() { this->f(); }
};

int main() { C<int> c; c.g(); }
struct A { protected: int B; };
typedef A B;

struct C : B {
  // inheriting constructor, instead of bringing A::B into scope
  using B::B;
};

int main() { C c; c.B = 0; }
#include <sstream>
#include <cassert>

int main()
{
   std::stringstream ss;
   ss << '!';
   
   int x = -1;
   
   assert(!(ss >> x)); // C++03 and C++11
   assert(x == -1);    // C++03
   assert(x == 0);     // C++11
}