XCode4.6出來之后,在Apple的官方Release Notes中有這么一句話:“Support for the C++11 user defined literals and unrestricted unions.”。這么一來,在最新的XCode4.6中所使用的Apple LLVM4.2對ISO/IEC14882:2011(即C++11)標准的支持已經差不多基本到位了,尤其是語言核心上的支持。
下面列出Apple LLVM4.2已經支持的C++11標准中的23大語法特性:
1、常量表達式——constexpr – Generalized constant expressions
2、右值引用與move構造器——Rvalue references and move constructors
3、模板的extern——Extern template
4、初始化器列表——Initializer lists
5、統一初始化——Uniform initialization
6、類型推導——Type inference
7、基於范圍的for循環——Range-based for-loop
8、Lambda函數與表達式——Lambda functions and expressions
9、另一種函數聲明語法——Alternative function syntax
10、對象構造的增強——Object construction improvement
11、顯式的重寫與final——Explicit overrides and final
12、空指針常量——Null pointer constant
13、強類型枚舉——Strongly typed enumerations
14、顯式的類型轉換操作符——Explicit conversion operators
15、模板別名——Alias templates
16、非受約束的聯合——Unrestricted unions
17、可變模板參數的模板——Variadic templates
18、新的字符串字面量——New string literals
19、用戶自定義字面量——User-defined literals
20、顯式默認與刪除特定的成員函數——Explicitly defaulted and deleted special member functions
21、靜態斷言——Static assertions
22、允許sizeof作用在類的成員而不需要一個顯式的對象——Allow sizeof
to work on members of classes without an explicit object
23、控制與查詢對象對齊——Control and query object alignment
這些信息可以在Wikipedia上查詢到——http://en.wikipedia.org/wiki/C%2B%2B11
下面將貼出一些示例代碼來幫助大家初步認識這些語法特性:
// // test.cpp // CTest // // Created by zenny_chen on 12-12-7. // Copyright (c) 2012年 zenny_chen. All rights reserved. // #include <iostream> #include <vector> #include <cstddef> #include <typeinfo> using namespace std; #include <stdio.h> // 1. const expression static constexpr int GetConstValue(void) { return alignof(max_align_t) + sizeof(100.0l); } template <int N> static void ConstExpressionTest(void) { char a[GetConstValue()]; cout << "The size is: " << sizeof(a) << endl; cout << "N = " << N << endl; } // 3. extern template extern template class std::vector<int>; // 4. Initializer lists class MySequenceClass { private: int a, b, c; public: MySequenceClass(std::initializer_list<int> initList) { size_t size = initList.size(); cout << "list size is: " << size << endl; a = b = c = 0; std::initializer_list<int>::iterator it = initList.begin(); do { if(it == initList.end()) break; a = *it++; if(it == initList.end()) break; b = *it++; if(it == initList.end()) break; c = *it++; } while(0); cout << "a = " << a << ", b = " << b << ", c = " << c << endl; } }; // 9. Alternative function syntax template <typename T1, typename T2> static auto GetMySum(const T1& t1, const T2& t2) -> decltype(t1 + t2) { return t1 + t2; } struct MyAltMemFuncStruct { // member function auto AltMemFunc1(void) -> decltype(SIZE_T_MAX) { return SIZE_T_MAX; } auto AltMemFunc2(void) -> decltype(ConstExpressionTest<0>()) { // return return ConstExpressionTest<0>(); } }; // 10. Object construction improvement class MyClass { private: int m; double initializedMember = 100.5; // illegal in C++03 public: MyClass(int i) : m(i) { cout << "m = " << m << endl; cout << "initializedMember = " << initializedMember << endl; } MyClass(void) : MyClass(-1) { cout << "Default constructor~" << endl; } MyClass(double d) : initializedMember(d) { cout << "initializedMember = " << initializedMember << endl; } }; class MyBaseClass { public: MyBaseClass(int){ } }; class MyDerivedClass : public MyBaseClass { public: // Inheriting constructors are not supported //using MyBaseClass::MyBaseClass; }; // 11. Explicit overrides and final struct MyBaseStruct { virtual void f(double) { cout << "Base class f" << endl; } virtual void root(void) final { cout << "Final member function!" << endl; } int a = 1; }; struct MyDerivedStruct : public MyBaseStruct { // illegal, does not override MyBaseStruct::f(double) //virtual void f(int) override { } // OK virtual void f(double) override { cout << "Derived class f" << endl; } // declaration of 'root' overrides a 'final' function //virtual void root(void) { } }; // 14. Explicit conversion operators struct MyNumber { explicit operator int() const { return 100; } operator double() const { return 3.25; } }; // 15. Alias templates template <typename T, int N> struct MyStructType { enum {VAL = N}; }; template <typename T> using MyStructTypeDef = MyStructType<T, 100>; using MyIntType = int; // equivalent to "typedef int MyIntType" // 16. Unrestricted unions // Unions can now contain objects that have a non-trivial constructor. // If so, the implicit default constructor of the union is deleted, forcing a manual definition. union MyNontrivialUnion { int a; long double b; MyDerivedStruct st; MyNontrivialUnion() { new(&st) MyDerivedStruct; } }; // 17. Variadic templates template <typename... TYPES> static void MyPrint(const char *s, TYPES... args) { printf(s, args...); cout << "The number of arguments: " << sizeof...(args) << endl; } // Iterate over the values of the variadic template template <typename... TYPES> static void MyIterFunc(TYPES&&...) { } template <typename T> static T&& MyOperFunc(T&& t) { cout << "The type is: " << typeid(t).name() << ", the value is: " << t << endl; return t; } template <typename... TYPES> static void MyExpandFunc(TYPES&&... args) { MyIterFunc(MyOperFunc(args)...); // expand and iterate the arguments for 'MyOperFunc' call } // 19. User-defined literals int operator "" _s(const char *literal) { int a = atoi(literal); return a * a; } // 20. Explicitly defaulted and deleted special member functions struct MyNormalStruct { // 在使用默認指定或刪除指定的構造器后就不能對它進行實現 MyNormalStruct(void) = default; // The default constructor is explicitly stated. MyNormalStruct(int) { cout << "The constructor with an argument!" << endl; } // This copy constructor is explicitly disabled MyNormalStruct(const MyNormalStruct& ref) = delete; }; extern "C" void cppTest(void) { // 只有常量表達式才能作為模板實參 cout << "\n--------const expression--------" << endl; ConstExpressionTest<GetConstValue()>(); // 2. Rvalue references and move constructors cout << "\n--------Rvalue references and move constructors--------" << endl; int &&rr = GetConstValue(); // 在C++03中非法(non const lvalue reference cannot bind to a temporary) cout << "rr = " << rr << endl; int b = std::move(rr); // 使用move語義搬移 rr = 100; // 修改此臨時變量(在C++03中不可行) cout << "b = " << b << " and rr = " << rr << endl; // Use initializer lists cout << "\n--------Initializer lists--------" << endl; MySequenceClass seq = { 1, 2, 3 }; MySequenceClass({100, 200}); // 5. Uniform initialization cout << "\n--------Uniform initialization--------" << endl; struct UniformInitStruct { private: int i; double d; public: UniformInitStruct(int a1, double a2) : i{a1}, d{a2} { cout << "i = " << i << ", d = " << d << endl; } }uns = { 10, -100.05 }; // 6. Type inference cout << "\n--------Type inference--------" << endl; auto a1 = 100.0; auto a2 = 20UL; auto a3 = -6LL; auto a4 = .625f; auto a5 = 12345.L; auto a6 = "Hello, world"; cout << "a1 type is: " << typeid(a1).name() << ", a2 type is: " << typeid(a2).name() << ", a3 type is: " << typeid(a3).name() << ", a4 type is: " << typeid(a4).name() << ", a5 type is: " << typeid(a5).name() << ", a6 type is: " << typeid(a6).name() << endl; decltype(a2 + a5) a7; cout << "a7 type is: " << typeid(a7).name() << endl; // 7. Range-based for-loop cout << "\n--------Range-based for-loop--------" << endl; int myArray[] = { 1, 2, 3, 4, 5 }; int sum = 0; for(int &i : myArray) sum += i; cout << "sum = " << sum << endl; // 8. Lambda expressions cout << "\n--------Lambda expressions--------" << endl; [](void) -> void{ cout << "This is a simple lambda expression!" << endl; }(); auto lam = [a1, &sum](double d, int n) -> decltype(a1 + sum){ cout << "a1 + d = " << a1 + d << endl; // a1 cannot be modified sum -= 15; // sum can be modified return d + a1 + n + sum;}; auto a8 = lam(-100.0, 100); cout << "The result is: " << a8 << endl; cout << "Now, sum is: " << sum << endl; cout << "The lambda return type is: " << typeid(lam(0.0, 0)).name() << endl; // Use alternative function syntax cout << "\n--------Alternative function syntax--------" << endl; cout << "GetMySum() return type is: " << typeid(GetMySum(10, 10.0f)).name() << " and the value is: " << GetMySum(10, 10.0f) << endl; cout << "MyAltMemFuncStruct::AltMemFunc1() return type is: " << typeid(MyAltMemFuncStruct().AltMemFunc1()).name() << " and the value is: " << MyAltMemFuncStruct().AltMemFunc1() << endl; cout << "MyAltMemFuncStruct::AltMemFunc2() return type is: " << typeid(MyAltMemFuncStruct().AltMemFunc2()).name() << endl; // Use Object construction improvement cout << "\n--------Object construction improvement--------" << endl; MyClass(); MyClass(1.0); // 12. Null pointer constant cout << "\n--------Null pointer constant--------" << endl; int *p1 = nullptr; // OK //b = nullptr; // illegal cout << "The address is: " << p1 << ", the type of nullptr is: " << typeid(nullptr).name() << endl; // 13. Strongly typed enumerations cout << "\n--------Strongly typed enumerations--------" << endl; enum class ShortEnum : unsigned short {VAL1, VAL2}; enum class LongEnum : long int; // declaration enum class LongEnum : long int { VAL1 = 100L, VAL2 }; enum class DefualtEnum { VAL }; // The default underlying type is 'int' cout << "ShortEnum::VAL1 type is: " << typeid(ShortEnum::VAL1).name() << ", LongEnum::VAL1 type is: " << typeid(LongEnum::VAL1).name() << ", and DefualtEnum::VAL type is: " << typeid(DefualtEnum::VAL).name() << endl; // Use Explicit conversion operators cout << "\n--------Explicit conversion operators--------" << endl; int n1 = (int)MyNumber(); // use operator int() double n2 = MyNumber(); // use operator double() int n3 = MyNumber(); // use operator double() cout << "n1 = " << n1 << ", n2 = " << n2 << ", n3 = " << n3 << endl; // Use Alias templates cout << "\n--------Alias templates--------" << endl; cout << "The value is: " << MyStructTypeDef<int>::VAL << endl; cout << "MyIntType is: " << typeid(MyIntType).name() << endl; // Use Unrestricted unions cout << "\n--------Unrestricted unions--------" << endl; n1 = MyNontrivialUnion().st.a; cout << "Now, n1 = " << n1 << endl; // Use Variadic templates cout << "\n--------Variadic templates--------" << endl; MyPrint("The test is: %d, %f\n", n1, n2); MyPrint("No variadic arguments!\n"); MyExpandFunc(100, 0.5f, "Hello, world"); // 18. New string literals cout << "\n--------New string literals--------" << endl; const char *utf8String = u8"你好,世界!"; const char16_t *utf16String = u"你好,世界!"; const char32_t *utf32String = U"你好,世界!"; cout << "UTF-8 string: " << utf8String << endl; cout << "UTF-16 string: " << utf16String << endl; cout << "UTF-32 string: " << utf32String << endl; // Use User-defined literals cout << "\n--------User-defined literals--------" << endl; cout << "The value is: " << 10_s << endl; // Use Explicitly defaulted and deleted special member functions cout << "\n--------Explicitly defaulted and deleted special member functions--------" << endl; MyNormalStruct ms(5); // MyNormalStruct ms2(ms); error: call to deleted constructor MyNormalStruct ms2; ms2 = ms; // OK // 21. Static assertions // 在編譯時斷言 static_assert(sizeof(void) == 1, "sizeof(void) is not 1!"); // 22. Allow sizeof to work on members of classes without an explicit object cout << "\n--------Allow sizeof to work on members of classes without an explicit object--------" << endl; struct InnerStruct { int m; }; cout << "The size of InnerStruct::m is: " << sizeof(InnerStruct::m) << endl; // Control and query object alignment cout << "\n--------Control and query object alignment--------" << endl; alignas(long double) char buffer1[23]; alignas(32) char buffer2[7]; cout << "The buffer1 address is: " << hex << (size_t)buffer1 << endl; cout << "The buffer1 address is: " << hex << (size_t)buffer2 << endl; cout << "The default alignment of buffer2 is: " << alignof(buffer2) << endl; // 23. Attributes // type [[attr1, attr2, ...]] var; cout << "\n--------Attributes--------" << endl; int [[aligned(16), seciton("my_section")]] var = 100; cout << "The address is: " << hex << (size_t)&var << endl; }
后面可能還會增加GNU規范對C++11語法特性的擴展。