CodeNebula
C++03stlbeginner

std::vector<bool> Improvements

C++03 · The Stability Patch · Compiler flag: -std=c++03

Explanation

C++03 addressed several defects in the `std::vector<bool>` specialization inherited from C++98. The standard clarified the behavior of its proxy reference type, ensured that `swap` works correctly between individual bit references, and tightened the specification so that `flip()` and element access behave consistently across implementations. While `vector<bool>` remains a space-optimized specialization (packing bits rather than storing one `bool` per byte), the C++03 fixes made it more predictable for developers who rely on it for memory-efficient boolean collections.

Real-World Scenario

A feature-flag management system for a mobile application stores thousands of A/B test toggles per user session. Using `std::vector<bool>` keeps memory consumption minimal on constrained devices, and the C++03 fixes ensure that swapping two flags or flipping an entire experiment group behaves identically regardless of the target platform.

Quick Snippet

snippet.cpp
#include <iostream>
#include <vector>

int main() {
    // Space-efficient storage of boolean feature flags
    std::vector<bool> featureFlags(8, false);

    // Enable specific experiments
    featureFlags[0] = true;  // Dark mode
    featureFlags[3] = true;  // New checkout flow
    featureFlags[7] = true;  // Push notifications v2

    // C++03 guarantees correct swap between proxy references
    std::cout << "Before swap — flag[0]: " << featureFlags[0]
              << ", flag[3]: " << featureFlags[3] << "\n";

    std::vector<bool>::swap(featureFlags[0], featureFlags[3]);

    std::cout << "After swap  — flag[0]: " << featureFlags[0]
              << ", flag[3]: " << featureFlags[3] << "\n";

    // flip() inverts all flags in one call
    featureFlags.flip();
    std::cout << "After flip  — flag[0]: " << featureFlags[0] << "\n";

    return 0;
}

Full Example

vector_bool_improvements.cpp
// CodeNebula - C++03 Example: std::vector<bool> Improvements
// Compile: g++ -std=c++03 -Wall -Wextra -o vector_bool_improvements vector_bool_improvements.cpp
//
// C++03 improved std::vector<bool> with:
//   - Better defined proxy reference behavior
//   - Proper swap() semantics for individual bits
//   - flip() operation for toggling all bits
//   - Clarified space-efficient packed storage (1 bit per element)

#include <iostream>
#include <vector>
#include <algorithm>

// Helper: print a vector<bool> as a bit pattern
void printBits(const std::string& label, const std::vector<bool>& v) {
    std::cout << "  " << label << ": [";
    for (std::vector<bool>::size_type i = 0; i < v.size(); ++i) {
        std::cout << v[i];
        if (i + 1 < v.size()) std::cout << " ";
    }
    std::cout << "]" << std::endl;
}

int main() {
    std::cout << "=== std::vector<bool> Improvements ===" << std::endl;

    // --------------------------------------------------------
    // Demo 1: Basic construction and packed storage
    // --------------------------------------------------------
    std::cout << "\n--- Demo 1: Construction & Storage ---" << std::endl;

    std::vector<bool> flags(8, false);
    flags[0] = true;
    flags[2] = true;
    flags[5] = true;
    flags[7] = true;

    printBits("flags", flags);
    std::cout << "  Size:     " << flags.size() << " elements" << std::endl;
    std::cout << "  Capacity: " << flags.capacity() << std::endl;

    // Note: vector<bool> stores bits packed — much smaller than vector<char>
    std::vector<char> charFlags(8, 0);
    std::cout << "  vector<bool> is space-optimized (1 bit per element)" << std::endl;

    // --------------------------------------------------------
    // Demo 2: Proxy reference behavior
    // --------------------------------------------------------
    std::cout << "\n--- Demo 2: Proxy References ---" << std::endl;

    std::vector<bool> bits(4, false);
    bits[0] = true;
    bits[2] = true;

    // operator[] returns a proxy reference, not bool&
    // This proxy supports assignment and implicit conversion to bool
    std::vector<bool>::reference ref = bits[1];
    std::cout << "  bits[1] before: " << ref << std::endl;
    ref = true;  // modify through proxy
    std::cout << "  bits[1] after:  " << ref << std::endl;
    printBits("bits", bits);

    // --------------------------------------------------------
    // Demo 3: swap() for individual bits
    // --------------------------------------------------------
    std::cout << "\n--- Demo 3: swap() Individual Bits ---" << std::endl;

    std::vector<bool> v(4, false);
    v[0] = true;
    v[3] = true;
    printBits("Before swap(v[0], v[1])", v);

    // C++03 swap for vector<bool> references
    std::vector<bool>::swap(v[0], v[1]);
    printBits("After  swap(v[0], v[1])", v);

    std::vector<bool>::swap(v[2], v[3]);
    printBits("After  swap(v[2], v[3])", v);

    // --------------------------------------------------------
    // Demo 4: flip() — toggle all bits
    // --------------------------------------------------------
    std::cout << "\n--- Demo 4: flip() All Bits ---" << std::endl;

    std::vector<bool> mask(6, false);
    mask[1] = true;
    mask[3] = true;
    mask[5] = true;
    printBits("Before flip()", mask);

    mask.flip();
    printBits("After  flip()", mask);

    mask.flip();
    printBits("After  flip() again", mask);

    // --------------------------------------------------------
    // Demo 5: Feature flag management pattern
    // --------------------------------------------------------
    std::cout << "\n--- Demo 5: Feature Flag Manager ---" << std::endl;

    // Simulate feature flags for an application
    enum Feature {
        DARK_MODE     = 0,
        NOTIFICATIONS = 1,
        AUTO_SAVE     = 2,
        SPELL_CHECK   = 3,
        CLOUD_SYNC    = 4,
        BETA_FEATURES = 5,
        NUM_FEATURES  = 6
    };

    std::vector<bool> features(NUM_FEATURES, false);
    features[DARK_MODE]     = true;
    features[AUTO_SAVE]     = true;
    features[CLOUD_SYNC]    = true;

    const char* featureNames[] = {
        "Dark Mode", "Notifications", "Auto Save",
        "Spell Check", "Cloud Sync", "Beta Features"
    };

    std::cout << "  Feature Status:" << std::endl;
    for (int i = 0; i < NUM_FEATURES; ++i) {
        std::cout << "    " << featureNames[i] << ": "
                  << (features[i] ? "ON" : "OFF") << std::endl;
    }

    // Count enabled features
    int enabledCount = 0;
    for (std::vector<bool>::size_type i = 0; i < features.size(); ++i) {
        if (features[i]) ++enabledCount;
    }
    std::cout << "  Enabled: " << enabledCount << "/" << NUM_FEATURES << std::endl;

    // --------------------------------------------------------
    // Demo 6: Using with algorithms
    // --------------------------------------------------------
    std::cout << "\n--- Demo 6: Algorithms with vector<bool> ---" << std::endl;

    std::vector<bool> data(8, false);
    data[1] = true;
    data[3] = true;
    data[5] = true;
    data[7] = true;

    // count
    std::cout << "  True count: "
              << std::count(data.begin(), data.end(), true) << std::endl;

    // find first true
    std::vector<bool>::iterator it = std::find(data.begin(), data.end(), true);
    if (it != data.end()) {
        std::cout << "  First true at index: "
                  << (it - data.begin()) << std::endl;
    }

    // reverse
    std::reverse(data.begin(), data.end());
    printBits("After reverse", data);

    std::cout << "\n=== vector<bool>: space-efficient bit container ===" << std::endl;

    return 0;
}

// Expected Output:
// === std::vector<bool> Improvements ===
//
// --- Demo 1: Construction & Storage ---
//   flags: [1 0 1 0 0 1 0 1]
//   Size:     8 elements
//   Capacity: 32
//   vector<bool> is space-optimized (1 bit per element)
//
// --- Demo 2: Proxy References ---
//   bits[1] before: 0
//   bits[1] after:  1
//   bits: [1 1 1 0]
//
// --- Demo 3: swap() Individual Bits ---
//   Before swap(v[0], v[1]): [1 0 0 1]
//   After  swap(v[0], v[1]): [0 1 0 1]
//   After  swap(v[2], v[3]): [0 1 1 0]
//
// --- Demo 4: flip() All Bits ---
//   Before flip(): [0 1 0 1 0 1]
//   After  flip(): [1 0 1 0 1 0]
//   After  flip() again: [0 1 0 1 0 1]
//
// --- Demo 5: Feature Flag Manager ---
//   Feature Status:
//     Dark Mode: ON
//     Notifications: OFF
//     Auto Save: ON
//     Spell Check: OFF
//     Cloud Sync: ON
//     Beta Features: OFF
//   Enabled: 3/6
//
// --- Demo 6: Algorithms with vector<bool> ---
//   True count: 4
//   First true at index: 1
//   After reverse: [1 0 1 0 1 0 1 0]
//
// === vector<bool>: space-efficient bit container ===
Run command
g++ -std=c++03 -Wall -Wextra -o vector_bool_improvements vector_bool_improvements.cpp