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语法特性的扩展。