void


Keyword: void

The void keyword in C++ is used to indicate the absence of a type or value. It has several important uses in the language, primarily in function declarations and pointer manipulation. Understanding void is crucial for writing flexible and efficient C++ code.

Key Characteristics

Example 1: Functions Returning void

#include <iostream>

void printMessage(const std::string& message) {
    std::cout << message << std::endl;
}

void modifyValue(int& value) {
    value *= 2;
}

int main() {
    printMessage("Hello, World!");

    int number = 5;
    std::cout << "Before: " << number << std::endl;
    modifyValue(number);
    std::cout << "After: " << number << std::endl;

    return 0;
}

Explanation:

Example 2: Functions with No Parameters

#include <iostream>
#include <ctime>

void printCurrentTime() {
    time_t now = time(0);
    std::cout << "Current time: " << ctime(&now);
}

int main() {
    printCurrentTime();
    return 0;
}

Explanation:

Example 3: void Pointers

#include <iostream>

void printValue(void* ptr, char type) {
    switch(type) {
        case 'i':
            std::cout << "Integer value: " << *static_cast<int*>(ptr) << std::endl;
            break;
        case 'd':
            std::cout << "Double value: " << *static_cast<double*>(ptr) << std::endl;
            break;
        case 'c':
            std::cout << "Char value: " << *static_cast<char*>(ptr) << std::endl;
            break;
    }
}

int main() {
    int i = 5;
    double d = 3.14;
    char c = 'A';

    printValue(&i, 'i');
    printValue(&d, 'd');
    printValue(&c, 'c');

    return 0;
}

Explanation:

Example 4: Explicit Void Casting

#include <iostream>

class Base {
public:
    virtual void print() const {
        std::cout << "Base class" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() const override {
        std::cout << "Derived class" << std::endl;
    }
};

int main() {
    Derived d;
    Base* bp = &d;

    bp->print();  // Calls Derived::print()

    // Explicitly call Base::print using void cast
    (static_cast<void (Base::*)() const>(&Base::print))(bp);

    return 0;
}

Explanation:

Example 5: void as a Template Parameter

#include <iostream>
#include <type_traits>

template<typename T>
struct Helper {
    static void print() {
        std::cout << "Non-void type" << std::endl;
    }
};

template<>
struct Helper<void> {
    static void print() {
        std::cout << "Void type" << std::endl;
    }
};

template<typename T>
void process() {
    Helper<T>::print();
}

// Overload for void
void process() {
    Helper<void>::print();
}

int main() {
    process<int>();
    process<void>();
    process();  // Calls the non-template overload

    return 0;
}

Explanation

  1. We removed the default template argument from Helper.
  2. Instead of using a default template argument for process, we added a non-template overload of process() that calls Helper<void>::print().
  3. Now, process(); in main() calls the non-template overload, which effectively gives us the behavior we wanted.

For C++14 and above

For C++14 and later versions, you can use default template arguments for function templates. Here's how you could write it for C++14 and above:

#include <iostream>
#include <type_traits>

template<typename T>
struct Helper {
    static void print() {
        std::cout << "Non-void type" << std::endl;
    }
};

template<>
struct Helper<void> {
    static void print() {
        std::cout << "Void type" << std::endl;
    }
};

template<typename T = void>
void process() {
    Helper<T>::print();
}

int main() {
    process<int>();
    process<void>();
    process<>();  // Defaults to void in C++14 and later

    return 0;
}

In this C++11 version:

Additional Considerations

  1. C-style Void Pointers: In C, void* can be implicitly converted to any pointer type, but C++ requires explicit casting.

  2. Function Pointers: void (*)() represents a pointer to a function that returns nothing and takes no parameters.

  3. Member Function Pointers: void (ClassName::*)() represents a pointer to a member function of ClassName that returns nothing and takes no parameters.

  4. std::void_t: A utility metafunction in C++17 used in template metaprogramming.

  5. Incomplete Types: void is considered an incomplete type and cannot be used to declare variables or as a function return type (except for functions returning void).

Summary

void in C++ serves several important purposes:

  1. Indicates functions that don't return a value.
  2. Represents an empty parameter list in function declarations.
  3. Creates generic pointers that can point to any type.
  4. Used in explicit type casting, especially with virtual functions.
  5. Serves as a template parameter in template metaprogramming.

Key points to remember:

Best practices:

The void keyword is a fundamental part of C++ that provides flexibility in function declarations, pointer manipulation, and template metaprogramming, contributing to the language's expressiveness and power.

Related

Previous Page | Course Schedule | Course Content