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語法特性的擴展。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM