Apple LLVM4.2对C++11标准的支持

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

你可能感兴趣的:(apple)