มีการเปลี่ยนแปลงอะไรใหม่ใน C ++ 11


227

ฉันรู้ว่าอย่างน้อยหนึ่งของการเปลี่ยนแปลงใน C ++ 11 ที่จะทำให้เกิดรหัสเดิมบางส่วนที่จะหยุดการรวบรวม: แนะนำของในห้องสมุดมาตรฐานแทนที่กรณีเก่าexplicit operator bool() operator void*()ได้รับรหัสที่ว่านี้จะทำลายอาจเป็นรหัสที่ไม่ควรถูกต้องในสถานที่แรก แต่มันก็ยังคงเป็นการเปลี่ยนแปลงที่แตกหัก: โปรแกรมที่เคยใช้ไม่ถูกต้องอีกต่อไป

มีการเปลี่ยนแปลงที่แตกหักอื่น ๆ อีกหรือไม่?


1
การลบความหมายของexportคำหลักออกไหม ฉันจะรับเสื้อโค้ท
Steve Jessop

7
คุณจะรู้ว่าฉันจะไม่เรียกมันว่าการเปลี่ยนแปลงของการแปลงเป็นบูลเป็น "การเปลี่ยนแปลงที่ผิดเพี้ยน" ... มากขึ้นเช่น "การเปลี่ยนแปลงการลงโทษ"
Xeo

4
เมื่อเอกสารทั้งหมดที่จำเป็นในการสร้างสหภาพดังกล่าวกำลังรอให้มีการประทับตรายางแน่นอนทำไมไม่
Dennis Zickefoose

3
@Xeo: mystream.good()ไม่เหมือนกันbool(mystream)หรือ good()เป็นจริงถ้าไม่มีการตั้งค่าสถานะ bool(mystream)ยังคงเป็นเท็จหากeofbitตั้งค่าไว้เท่านั้น !mystream.fail()จะเทียบเท่าที่ถูกต้อง
R. Martinho Fernandes

2
ผู้ดำเนินรายการหมายเหตุ : " โปรดแสดงความคิดเห็นในหัวข้อที่มีคำถามหรือคำตอบอยู่ในมือเมื่อพูดคุยคำถามหรือคำตอบการสนทนาควรจะเกี่ยวกับสิ่งนั้นคำถามหรือคำตอบในมือการโต้วาทีโดยทั่วไปไม่สร้างสรรค์สำหรับ Stack Overflow การทำให้เป็นศัตรูกันไม่ได้แน่นอน "
Tim Post

คำตอบ:


178

FDIS มีส่วนสำหรับความเข้ากันไม่ได้ที่ภาคผนวกC.2"C ++ และ ISO C ++ 2003"

สรุปถอดความ FDIS ที่นี่เพื่อให้เหมาะสมกับคำตอบ SO (ดีกว่า) ฉันเพิ่มตัวอย่างของฉันเองเพื่อแสดงความแตกต่าง

มีความเข้ากันไม่ได้ที่เกี่ยวข้องกับห้องสมุดอยู่สองสามอย่างที่ฉันไม่รู้ความหมายของสิ่งนั้นดังนั้นฉันจึงปล่อยให้คนอื่น ๆ ทำอย่างละเอียด

ภาษาหลัก


#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"

#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .

คำหลักใหม่: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert และ thread_local


ตัวอักษรจำนวนเต็มบางตัวที่ใหญ่กว่าความยาวที่สามารถแทนด้วยความยาวอาจเปลี่ยนจากประเภทจำนวนเต็มที่ไม่ได้ลงชื่อไปเป็นแบบยาวที่ลงนามแล้ว


รหัส C ++ 2003 ที่ถูกต้องที่ใช้การหารจำนวนเต็มปัดผลลัพธ์เป็น 0 หรือไปทางอนันต์ลบในขณะที่ C ++ 0x จะปัดผลลัพธ์เป็น 0 เสมอ

(จริงๆแล้วไม่ใช่ปัญหาความเข้ากันได้สำหรับคนส่วนใหญ่)


รหัส C ++ 2003 ที่ถูกต้องที่ใช้คำหลักautoเป็นตัวระบุคลาสหน่วยเก็บข้อมูลอาจไม่ถูกต้องใน C ++ 0x


การแปลงที่แคบทำให้เกิดความไม่เข้ากันกับ C ++ 03 ตัวอย่างเช่นรหัสต่อไปนี้ถูกต้องใน C ++ 2003 แต่ไม่ถูกต้องในมาตรฐานสากลนี้เนื่องจาก double to int เป็นการแปลงที่แคบลง:

int x[] = { 2.0 };

ฟังก์ชันสมาชิกพิเศษที่ประกาศโดยนัยจะถูกลบโดยไม่ได้ตั้งใจเมื่อคำนิยามโดยนัยจะมีรูปแบบไม่ดี

โปรแกรม C ++ 2003 ที่ถูกต้องซึ่งใช้หนึ่งในฟังก์ชันพิเศษของสมาชิกเหล่านี้ในบริบทที่ไม่จำเป็นต้องใช้คำจำกัดความ (เช่นใน expresion ที่ไม่อาจประเมินได้) กลายเป็นรูปแบบที่ไม่ถูกต้อง

ตัวอย่างจากฉัน:

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

เทคนิค SFINAE ขนาดดังกล่าวถูกใช้ไปแล้วและต้องการเปลี่ยนตอนนี้ :)


destructors ที่ผู้ใช้ประกาศมีข้อกำหนดข้อยกเว้นโดยนัย

ตัวอย่างจากฉัน:

struct A {
  ~A() { throw "foo"; }
};

int main() { try { A a; } catch(...) { } }

รหัสนี้เรียกใช้terminateใน C ++ 0x แต่ไม่ได้อยู่ใน C ++ 03 เนื่องจากข้อกำหนดข้อยกเว้นโดยนัยของA::~Aใน C ++ 0x noexcept(true)เป็น


การประกาศ C ++ 2003 ที่ถูกต้องมีexportอยู่ในรูปแบบไม่ถูกต้องใน C ++ 0x


นิพจน์ C ++ 2003 ที่ถูกต้องซึ่งมี>ตามมาทันที>จะถูกถือว่าเป็นเทมเพลตสองรายการ

ใน C ++ 03 >>จะเป็นโทเค็นของตัวดำเนินการ shift เสมอ


อนุญาตการเรียกใช้ฟังก์ชันที่ขึ้นอยู่กับการเชื่อมโยงภายใน

ตัวอย่างจากฉัน:

static void f(int) { }
void f(long) { }

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

int main() { g(0); }

ใน C ++ 03 การโทรนี้f(long)แต่ใน C ++ 0x การโทรf(int)นี้ ควรสังเกตว่าในทั้ง C ++ 03 และ C ++ 0x การเรียกต่อไปนี้f(B)(บริบทการสร้างอินสแตนซ์ยังคงพิจารณาเฉพาะการประกาศการเชื่อมโยงภายนอกเท่านั้น)

struct B { };
struct A : B { };

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

static void f(A) { }
void f(B) { }

int main() { A a; g(a); }

การจับคู่ที่ดีกว่าf(A)นั้นไม่ได้เกิดขึ้นเนื่องจากไม่มีการเชื่อมโยงภายนอก


การเปลี่ยนแปลงห้องสมุด

รหัส C ++ 2003 ที่ถูกต้องที่ใช้ตัวระบุใด ๆ ที่เพิ่มในไลบรารีมาตรฐาน C ++ ของ C ++ 0x อาจไม่สามารถรวบรวมหรือสร้างผลลัพธ์ที่แตกต่างในมาตรฐานสากลนี้


รหัส C ++ 2003 ที่ถูกต้องที่#includesส่วนหัวพร้อมชื่อใหม่ส่วนหัวของไลบรารีมาตรฐาน C ++ 0x อาจไม่ถูกต้องในมาตรฐานสากลนี้


รหัส C ++ 2003 ที่ถูกต้องซึ่งได้รับการเรียบเรียงโดยคาดหวังว่าการแลกเปลี่ยนจะต้อง<algorithm>มี<utility>


posixขณะนี้namespace ส่วนกลางถูกสงวนไว้สำหรับการสร้างมาตรฐาน


ที่ถูกต้อง C ++ 2003 รหัสที่กำหนดoverride, final, carries_dependencyหรือnoreturnเป็นแมโครไม่ถูกต้องใน C ++ 0x


"อนุญาตการเรียกใช้ฟังก์ชันที่ขึ้นอยู่กับการเชื่อมโยงภายใน" คุณช่วยอธิบายเกี่ยวกับความแตกต่างระหว่างสองตัวอย่างได้ไหม? เห็นได้ชัดว่าฉันขาดอะไรไป
Dennis Zickefoose

@Dennis การเปลี่ยนแปลงเป็นที่รู้จักโดยopen-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#561 แม้ว่าพวกเขาจะไม่ได้แสดงความคิดเห็นเกี่ยวกับข้อเท็จจริง แต่บริบทการสร้างอินสแตนซ์ยังคงประกอบด้วยเพียงชุดของการประกาศที่มีการเชื่อมโยงภายนอกที่ประกาศก่อนจุดอินสแตนซ์ของความเชี่ยวชาญด้านเทมเพลตในหน่วยการแปลเดียวกัน ดังนั้นการเปลี่ยนแปลงที่ทำมีผลกับการค้นหาในบริบทการนิยาม
Johannes Schaub - litb

ในตัวอย่างแรกของฉันที่กำหนดฟังก์ชั่นการเชื่อมโยงภายในสามารถมองเห็นได้และพบได้ในบริบทความหมายของแม่แบบ ในตัวอย่างที่สองของฉันฟังก์ชันการเชื่อมโยงภายในจะต้องเป็นส่วนหนึ่งของบริบทการสร้างอินสแตนซ์ แต่เนื่องจากไม่เป็นเช่นนั้นจึงไม่สามารถพบได้
Johannes Schaub - litb

ฉันคิดว่ากรณีเดียวที่ปลอดภัยสำหรับบริบทการกำหนดเทมเพลตเพื่อค้นหาฟังก์ชันที่มีการเชื่อมโยงภายในคือเมื่อความเชี่ยวชาญเฉพาะเทมเพลตของฟังก์ชันนั้นอินสแตนซ์ instantiated อย่างชัดเจนใน TU เดียว (ที่กำหนดเท็มเพลต) และ TU อื่น ๆ ทั้งหมด การสร้างอินสแตนซ์ที่ชัดเจน ในกรณีอื่น ๆ ทั้งหมด (ที่ TU อื่น ๆ จะยกระดับความเชี่ยวชาญเฉพาะด้าน) คุณจะละเมิด ODR โดยให้คำจำกัดความของแม่แบบใช้ฟังก์ชั่นที่แตกต่างกัน (การเชื่อมโยงภายใน) ในแต่ละครั้ง
Johannes Schaub - litb

ดังนั้นฉันไม่แน่ใจว่าทำไมพวกเขายังคงมีข้อ จำกัด ในบริบทการสร้างอินสแตนซ์ - จะมีอินสแตนซ์เพียงหนึ่ง (ชัดเจน) และการสร้างอินสแตนซ์นั้นจะใช้ฟังก์ชันเชื่อมโยงภายในที่พบในบริบทการสร้างอินสแตนซ์ เช่นเดียวกับบริบทของคำนิยาม บังเอิญผมคิดว่าถ้าเรายังคงมีexportแล้วผมคิดว่าคนอื่น ๆ TUS จะไม่จำเป็นต้องพึ่งพา instantiation อย่างชัดเจน แต่อาจยกตัวอย่าง themselfs แม่แบบ จากนั้นมันจะสร้างความแตกต่างหรือไม่ว่าฟังก์ชั่นเชื่อมโยงภายในสามารถมองเห็นได้ในบริบทการสร้างอินสแตนซ์
Johannes Schaub - litb

28

ความหมายของคำหลักอัตโนมัติเปลี่ยนไป


9
หากคุณใช้autoคำหลักมีบางอย่างผิดปกติกับรหัสของคุณ ทำไมคุณถึงใช้บนโลกนี้?
Elazar Leibovich

นั่นไม่ใช่การเปลี่ยนแปลงทำลาย การใช้ C ++ 03 ที่autoถูกต้องจะยังคงใช้ได้ใน C ++ 11
Drew Dormann

11
@DrewDormann int main() { auto int i = 0; return i; }นั้นถูกต้อง C ++ 03 แต่มีข้อผิดพลาดทางไวยากรณ์ใน C ++ 11 คำเตือนเดียวที่ฉันสามารถคอมไพเลอร์เพื่อให้มันในโหมด C ++ 03 เป็นคำเตือนเกี่ยวกับความเข้ากันได้

24

ทำลายการเปลี่ยนแปลงหรือไม่

ดีสำหรับสิ่งหนึ่งถ้าคุณใช้decltype, constexpr, nullptrฯลฯ เป็นตัวบ่งชี้แล้วคุณอาจจะมีปัญหา ...


21

ความเข้ากันไม่ได้หลักบางอย่างที่ไม่ครอบคลุมในส่วนที่เข้ากันไม่ได้:


C ++ 0x ถือว่าชื่อคลาสที่ถูกฉีดเป็นเท็มเพลตหากชื่อถูกส่งเป็นอาร์กิวเมนต์ไปยังพารามิเตอร์เท็มเพลตเท็มเพลตและเป็นชนิดหากถูกส่งไปยังพารามิเตอร์ชนิดเท็มเพลต

รหัส C ++ 03 ที่ถูกต้องอาจทำงานแตกต่างกันหากอาศัยชื่อคลาสที่ถูกฉีดให้เป็นประเภทในสถานการณ์เหล่านี้เสมอ โค้ดตัวอย่างที่นำมาจาก clang PR ของฉัน

template<template<typename> class X>
struct M { };

template<template<typename> class X>
void g(int = 0); // #1

template<typename T>
void g(long = 0); // #2

template<typename T>
struct A {
  void f() {
    g<A>(); /* is ambiguous in C++0x */
    g<A>(1); /* should choose #1 in C++0x */
  }
};

void h() {
  A<int> a;
  a.f();
}

ใน C ++ 03 รหัสจะเรียกที่สองgทั้งสองครั้ง


C ++ 0x ทำให้บางชื่อที่ขึ้นกับใน C ++ 03 นั้นไม่ขึ้นอยู่กับตอนนี้ และต้องการการค้นหาชื่อสำหรับชื่อที่ไม่ผ่านการรับรองซึ่งอ้างถึงสมาชิกของเทมเพลตคลาสปัจจุบันเพื่อทำซ้ำในการสร้างอินสแตนซ์และต้องการการตรวจสอบว่าชื่อเหล่านี้ค้นหาแบบเดียวกับที่ทำในบริบทการกำหนดเทมเพลต

รหัส C ++ 03 ที่ถูกต้องซึ่งขึ้นอยู่กับกฎการปกครองอาจไม่ได้รวบรวมอีกต่อไปเนื่องจากการเปลี่ยนแปลงนี้

ตัวอย่าง:

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(); }

รหัส C ++ 03 ที่A<int>::fถูกต้องซึ่งการโทรไม่ถูกต้องใน C ++ 0x เนื่องจากการค้นหาชื่อเมื่อค้นหาอินสแตนซ์จะพบA<int>::fว่าตรงข้ามกับB::fก่อให้เกิดข้อขัดแย้งกับการค้นหาตามข้อกำหนด

ณ จุดนี้ยังไม่ชัดเจนว่าเป็นข้อบกพร่องใน FDIS หรือไม่ คณะกรรมการตระหนักถึงสิ่งนี้และจะประเมินสถานการณ์


การประกาศที่ใช้โดยที่ส่วนสุดท้ายเหมือนกับตัวระบุในส่วนสุดท้ายของตัวระบุในชื่อที่ผ่านการรับรองซึ่งแสดงถึงคลาสพื้นฐานซึ่งตอนนี้การใช้การประกาศจะตั้งชื่อนวกรรมิกแทนสมาชิกที่มีชื่อนั้น

ตัวอย่าง:

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; }

โค้ดตัวอย่างด้านบนมีรูปแบบที่ดีใน C ++ 03 แต่เกิดขึ้นไม่ดีใน C ++ 0x เนื่องจากA::Bยังไม่สามารถเข้าถึงmainได้


14

ความล้มเหลวในการดึงข้อมูลจะได้รับการปฏิบัติแตกต่างกัน

ตัวอย่าง

#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
}

เปลี่ยนข้อเสนอ

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23

การอ้างอิงมาตรฐาน

[C++03: 22.2.2.1.2/11]: ผลลัพธ์ของการประมวลผลสเตจ 2 สามารถเป็นหนึ่งใน

  • ลำดับของตัวอักษรได้รับการสะสมในระยะที่ 2 ที่เป็นแปลง (ตามกฎของscanf) valไปยังค่าของชนิดของ ค่านี้จะถูกเก็บไว้ในvalและถูกเก็บไว้ในios_base::goodbiterr
  • ลำดับของตัวอักษรที่สะสมในขั้นตอนที่ 2 จะทำให้scanfรายงานความล้มเหลวในการป้อนข้อมูล ได้รับมอบหมายให้ios_base::failbit [ed: ไม่มีการจัดเก็บอะไรเลย]errval

[C++11: 22.4.2.1.2/3]: [.. ]ค่าตัวเลขที่จะเก็บสามารถเป็นหนึ่งใน:

  • ศูนย์ถ้าฟังก์ชันแปลงล้มเหลวในการแปลงทั้งสนาม ได้รับมอบหมายให้ios_base::failbiterr
  • ค่า representable valบวกมากที่สุดถ้าเขตข้อมูลแสดงให้เห็นถึงความคุ้มค่าในเชิงบวกที่มีขนาดใหญ่เกินกว่าที่จะเป็นตัวแทนในการ ได้รับมอบหมายให้ios_base::failbiterr
  • valค่าแทนได้มากที่สุดเชิงลบหรือเป็นศูนย์สำหรับประเภทจำนวนเต็มไม่ได้ลงนามถ้าเขตข้อมูลแสดงให้เห็นถึงความคุ้มค่าในเชิงลบที่มีขนาดใหญ่เกินกว่าที่จะเป็นตัวแทนในการ ได้รับมอบหมายให้ios_base::failbiterr
  • ค่าที่แปลงแล้วมิฉะนั้น

valค่าตัวเลขผลลัพธ์จะถูกเก็บไว้ใน

การใช้งาน

  • GCC 4.8 แสดงผลถูกต้องสำหรับ C ++ 11 :

    การยืนยัน `x == -1 'ล้มเหลว

  • GCC 4.5-4.8 เอาต์พุตทั้งหมดสำหรับ C ++ 03ต่อไปนี้ซึ่งน่าจะเป็นข้อผิดพลาด:

    การยืนยัน `x == -1 'ล้มเหลว

  • Visual C ++ 2008 Expressแสดงผลอย่างถูกต้องสำหรับ C ++ 03:

    การยืนยันไม่สำเร็จ: x == 0

  • Visual C ++ 2012 Expressแสดงผลไม่ถูกต้องสำหรับ C ++ 11 ซึ่งดูเหมือนว่าจะเป็นปัญหาเกี่ยวกับสถานะการใช้งาน:

    การยืนยันไม่สำเร็จ: x == 0


13

การแนะนำตัวดำเนินการแปลงอย่างชัดเจนเป็นการเปลี่ยนแปลงที่ไม่คาดคิดอย่างไร เวอร์ชั่นเก่าจะยังคงเป็น "ถูกต้อง" เหมือนเดิม

ใช่การเปลี่ยนแปลงจากoperator void*() constเป็นexplicit operator bool() constจะเป็นการเปลี่ยนแปลงที่รุนแรง แต่หากถูกใช้ในลักษณะที่ผิดปกติเข้าและออกจากตัวเอง รหัสที่ใช้จะไม่ถูกทำลาย

ตอนนี้การเปลี่ยนแปลงที่ไม่หยุดยั้งคือการห้ามมิให้เกิดการ จำกัด การแปลงระหว่างการเริ่มต้นรวม :

int a[] = { 1.0 }; // error

แก้ไข : เพียงผู้จดจำstd::identity<T>จะถูกลบใน C ++ 0x (ดูหมายเหตุ) มันเป็นโครงสร้างความสะดวกสบายที่จะทำให้ประเภทขึ้นอยู่กับ เนื่องจาก struct ไม่ได้ทำอะไรมากจริง ๆ สิ่งนี้ควรแก้ไข:

template<class T>
struct identity{
  typedef T type;
};

หากวัตถุไลบรารีมาตรฐานมีการเพิ่มการแปลงอย่างชัดเจนการแปลงโดยนัยที่มีอยู่อาจหยุดทำงาน แต่ฉันไม่สามารถจินตนาการถึงสถานการณ์ที่การแปลงไม่ถูกต้องและทำสิ่งที่มีประโยชน์
Dennis Zickefoose

แนะนำคือการเปลี่ยนแปลงทำลายเพราะมันจะถูกแทนที่operator void*ที่มีอยู่
R. Martinho Fernandes

@Dennis: Aaah ฉันเห็นแล้วว่า @Martinho มีความหมายอย่างไร แต่มันจะเป็นการเปลี่ยนแปลงที่ไม่หยุดหย่อนถ้าคนใช้มันมากกว่าที่ตั้งใจ
Xeo

"แต่ถ้ามันถูกใช้ในทางที่ผิดและเข้าข้างตัวเอง" - bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }ไม่มีอะไรผิดปกติกับมันใน C ++ 03 แต่มันกลายเป็นข้อผิดพลาดใน C ++ 11 (หมายเหตุ: GCC 4.9 ยังคงมีoperator void*() constอยู่ที่นี่ซึ่งเป็นเหตุผลว่าทำไมจึงยอมรับรหัสในโหมด C ++ 11)

std::identity<T>ไม่ถูกลบใน C ++ 11 เนื่องจากไม่ได้เป็นส่วนหนึ่งของ C ++ 03 มันมีอยู่ในร่างสั้น ๆ สำหรับ C ++ 11 และถูกลบออกจากร่างก่อนมาตรฐาน
Howard Hinnant

8

มีการเปลี่ยนแปลงมากมายในไลบรารีคอนเทนเนอร์ที่อนุญาตโค้ดที่มีประสิทธิภาพมากขึ้น

ตัวอย่างเช่นการพิจารณาการstd::vectorก่อสร้างเริ่มต้น C ++ 0x และการเปลี่ยนแปลงที่ไม่เหมาะสม


7

มีการถกเถียงกันมากมาย ย้ายโดยปริยายที่ทำลายความเข้ากันได้แบบย้อนหลัง

( หน้าที่เก่ากว่าพร้อมการสนทนาที่เกี่ยวข้อง )

หากคุณอ่านลงในความคิดเห็นการย้ายกลับโดยปริยายก็เป็นการเปลี่ยนแปลงที่ไม่ดีเช่นกัน


ผลของการสนทนาเหล่านั้นคือถูกลบออกในเกือบทุกกรณี มีปัญหาอะไรกับสิ่งที่เหลืออยู่หรือไม่?
Dennis Zickefoose

@Dennis: ใช่ คำถามของคุณได้รับการตอบตอบแล้วและถกเถียงกันเรื่องความตายในหน้าการติดตามนี้
Ben Voigt

อ่าหน้ามือถือไม่ได้แสดงความคิดเห็น ไม่ว่าจะด้วยวิธีใดนั่นเป็นลิงก์ที่มีประโยชน์มากกว่า ... ความแปลกประหลาดในอดีตของกระบวนการมาตรฐานนั้นไม่เกี่ยวข้องเลย (เว้นแต่คุณกำลังใช้ MSVC ซึ่งฉันเชื่อว่าใช้ร่างแรกนั้น)
Dennis Zickefoose

@Dennis: ฉันคิดว่าคุณพูดถูก ย้ายลิงก์ไปรอบ ๆ คำตอบของฉัน
Ben Voigt

น่าเศร้าที่ cpp-next.com ไม่มีอยู่อีกต่อไป สำหรับการอ้างอิงในอนาคตเหล่านี้มีหน้าบันทึกโดย web.archive.org: ย้ายนัยหมดกันได้ย้อนหลังและหน้าเก่าที่มีการอภิปรายที่เกี่ยวข้อง
Max Truxa

6
struct x {
   x(int) {}
};

void f(auto x = 3) { }

int main() {
   f();
}

C ++ 03:ถูกต้อง

C ++ 0x: error: parameter declared 'auto'


2
@Xeo: รหัสถูกต้องใน C ++ 03 มันเป็นพารามิเตอร์ที่มีประเภทstruct xและไม่มีชื่อ
Ben Voigt

ฉันหวังว่าจะจับคนออก ฉันแค่หวังว่า @Xeo จะไม่ลบความคิดเห็นของเขาอย่างรวดเร็วเพราะฉันไม่ได้อ่าน!
Lightness Races ใน Orbit

@ Xeo: หากไม่มีการขุดผ่านไวยากรณ์ฉันมั่นใจว่า auto เป็นเพียงคำหลักที่ไม่ถูกต้อง ถ้าเป็นเช่นนั้นมันอาจทำงานได้ตามที่คุณคาดหวัง แต่นั่นอาจเป็นเรื่องยากที่จะกำหนดอย่างถูกต้อง
Dennis Zickefoose

สมมติว่าคุณจับฉัน มันไม่สนใจโครงสร้าง :)
Xeo

@ Tomalek: Xeo ได้ชี้อย่างถูกต้องว่า C ++ 03 ไม่มี int โดยนัย
Ben Voigt

-4

คุณสมบัติทางภาษา

  1. การเริ่มต้นสม่ำเสมอและทั่วไปโดยใช้ {}
  2. รถยนต์
  3. ป้องกันการตีบ
  4. constexpr
  5. ช่วงที่ใช้สำหรับลูป
  6. nullptr
  7. ชั้นเรียน Enum
  8. static_assert
  9. มาตรฐาน :: initializer_list
  10. การอ้างอิง Rvalue (ความหมายย้าย)
  11. >>
  12. lambdas
  13. เทมเพลต Variadic
  14. ประเภทและชื่อแทนแม่แบบ
  15. อักขระ Unicode
  16. ชนิดจำนวนเต็มแบบยาวขนาดยาว
  17. alignas และ alignof
  18. decltype
  19. ตัวอักษรสตริงดิบ
  20. POD ทั่วไป
  21. สหภาพแรงงานทั่วไป
  22. คลาสโลคัลเป็นอาร์กิวเมนต์เท็มเพลต
  23. ส่วนต่อท้ายไวยากรณ์ประเภทผลตอบแทน
  24. [[carry_dependency]] และ [[noreturn]]
  25. noexcept specifier
  26. ตัวดำเนินการ noexcept
  27. คุณสมบัติ C99:
    • ขยายประเภทที่สำคัญ
    • การต่อสตริงแคบ / กว้าง
    • _ _ STDC_HOSTED _ _
    • _Pragma (X)
    • แมโคร vararg และอาร์กิวเมนต์แมโครว่างเปล่า
  28. _ _ func _ _
  29. เนมสเปซแบบอินไลน์
  30. มอบหมายก่อสร้าง
  31. สมาชิกเริ่มต้นในกลุ่ม
  32. เริ่มต้นและลบ
  33. ตัวดำเนินการแปลงที่ชัดเจน
  34. ตัวอักษรที่ผู้ใช้กำหนด
  35. แม่แบบภายนอก
  36. อาร์กิวเมนต์แม่แบบเริ่มต้นสำหรับแม่แบบฟังก์ชัน
  37. สิ่งก่อสร้างที่สืบทอด
  38. แทนที่และครั้งสุดท้าย
  39. กฎ SFINAE ที่เรียบง่ายและทั่วไป
  40. รุ่นหน่วยความจำ
  41. thread_local

ส่วนประกอบไลบรารีมาตรฐาน

  1. initializer_list สำหรับคอนเทนเนอร์
  2. ย้ายซีแมนทิกส์สำหรับคอนเทนเนอร์
  3. forward_list
  4. ภาชนะแฮช
    • unordered_map
    • unordered_multimap
    • unordered_set
    • unordered_multiset
  5. ตัวชี้การจัดการทรัพยากร
    • unique_ptr
    • shared_ptr
    • weak_ptr
  6. สนับสนุนการเกิดพร้อมกัน
    • เกลียว
    • mutexes
    • ล็อค
    • ตัวแปรเงื่อนไข
  7. รองรับการทำงานพร้อมกันในระดับที่สูงขึ้น
    • packaged_thread
    • อนาคต
    • คำมั่นสัญญา
    • async
  8. tuples
  9. regex
  10. ตัวเลขสุ่ม
    • uniform_int_distribution
    • normal_distribution
    • random_engine
    • เป็นต้น
  11. ชื่อชนิดจำนวนเต็มเช่น int16_t, uint32_t และ int_fast64_t
  12. แถว
  13. คัดลอกและ rethrowing ข้อยกเว้น
  14. ระบบผิดพลาด
  15. การดำเนินการ emplace () สำหรับภาชนะบรรจุ
  16. ฟังก์ชั่น constexpr
  17. การใช้ฟังก์ชั่น noexcept อย่างเป็นระบบ
  18. ฟังก์ชั่นและผูก
  19. สตริงการแปลงค่าเป็นตัวเลข
  20. ตัวจัดสรรที่กำหนดขอบเขต
  21. ลักษณะประเภท
  22. อรรถประโยชน์ของเวลา: ระยะเวลาและ time_point
  23. อัตราส่วน
  24. quick_exit
  25. อัลกอริธึมเพิ่มเติมเช่น move (), copy_if () และ is_sorted ()
  26. เก็บขยะ ABI
  27. อะตอม

คุณสมบัติที่เลิกใช้แล้ว

  1. การสร้างตัวสร้างสำเนาและการมอบหมายให้ทำสำเนาสำหรับคลาสที่มีตัวทำลาย
  2. กำหนดสตริงตัวอักษรให้กับถ่าน *
  3. ข้อมูลจำเพาะข้อยกเว้น C ++ 98
    • unexcepted_handler
    • set_unexpected
    • get_unexpected
    • ไม่คาดฝัน
  4. ฟังก์ชั่นวัตถุและฟังก์ชั่นที่เกี่ยวข้อง
  5. auto_ptr
  6. การลงทะเบียน
  7. ++ บนบูล
  8. ส่งออก
  9. ดุจ C-style

3
นี่ไม่ได้ตอบคำถาม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.