收集一下奇奇怪怪的玩意(包括冷门用法)。。。。

虚函数的默认参数

#include <iostream>
using namespace std;

class Base {
public:
    virtual void show(int x = 10) = 0;

    virtual ~Base() { cout << "~Base\n"; }
};


class Derive : public Base {
public:
    void show(int x = 20) override {
        cout << "x = " << x << endl;
    }

    ~Derive() override { cout << "~Derive\n"; }
};

int main(int argc, char* argv[]) {
    Base* bb = new Derive();
    bb->show();
    delete(bb);

    return 0;
}

inline namespace

inline namespace 是 C++11 引入的一个特性,它允许命名空间中的成员被直接访问,就像它们在外层命名空间中一样。这主要用于版本控制和 ABI 兼容性。

基本用法

#include <iostream>
using namespace std;

namespace MyLib {
    inline namespace v1 {
        void func() {
            cout << "v1 version" << endl;
        }
    }
    
    namespace v2 {
        void func() {
            cout << "v2 version" << endl;
        }
    }
}

int main() {
    MyLib::func();      // 直接调用 inline namespace 中的函数
    MyLib::v2::func();  // 需要显式指定非 inline namespace
    
    return 0;
}

版本控制的陷阱

inline namespace 的一个常见陷阱是在版本切换时可能导致意外的名字冲突:

#include <iostream>
using namespace std;

namespace Library {
    inline namespace v1 {
        class Data {
        public:
            void process() { cout << "v1 processing" << endl; }
        };
    }
    
    namespace v2 {
        class Data {
        public:
            void process() { cout << "v2 processing" << endl; }
        };
    }
}

int main() {
    Library::Data d1;        // 使用 v1 版本(inline)
    // Library::v2::Data d2; // 这样可以显式使用 v2
    
    d1.process();
    
    // 陷阱:如果将来 v2 变成 inline,这段代码的行为会改变
    return 0;
}

ADL(参数依赖查找)中的 inline namespace

inline namespace 在 ADL 中行为特殊:

#include <iostream>
using namespace std;

namespace outer {
    inline namespace inner {
        struct MyType {};
        
        void process(MyType t) {
            cout << "inline namespace ADL" << endl;
        }
    }
}

int main() {
    outer::MyType obj;
    process(obj);  // ADL 会找到 inner::process,即使 inner 是 inline的
    
    return 0;
}

实际应用:标准库中的 inline namespace

标准库使用 inline namespace 来实现版本控制:

#include <iostream>
#include <string>

// 模拟标准库的实现
namespace std {
    inline namespace __1 {
        template<typename T>
        class vector {
        public:
            void push_back(const T& value) {
                std::cout << "vector::push_back" << std::endl;
            }
        };
    }
}

int main() {
    std::vector<int> v;  // 实际上是 std::__1::vector<int>
    v.push_back(42);
    
    return 0;
}

c++ alignas 和 alignof

alignas 是 C++11 引入的对齐说明符,用于指定变量或类型的对齐要求。

基本用法

#include <iostream>
using namespace std;

// 指定结构体16字节对齐
struct alignas(16) AlignedStruct {
    char data[8];
};

int main() {
    AlignedStruct s;
    cout << "Alignment: " << alignof(AlignedStruct) << endl;
    cout << "Size: " << sizeof(AlignedStruct) << endl;
    
    return 0;
}

变量对齐

#include <iostream>
using namespace std;

int main() {
    // 指定变量对齐
    alignas(32) int array[10];
    alignas(64) char buffer[128];
    
    cout << "Array alignment: " << alignof(decltype(array)) << endl;
    cout << "Buffer alignment: " << alignof(decltype(buffer)) << endl;
    
    return 0;
}

类成员对齐

#include <iostream>
using namespace std;

class MyClass {
public:
    char c;
    alignas(8) int i;  // 这个成员8字节对齐
    double d;
};

int main() {
    MyClass obj;
    cout << "Class size: " << sizeof(MyClass) << endl;
    cout << "Class alignment: " << alignof(MyClass) << endl;
    
    return 0;
}