Search code examples
c++headerlanguage-lawyerc++20c++-modules

How do C++ modules hide implementation details when they are in the same file as the interface?


I’m reading Bjarne Stroustrup’s A Tour of C++ (3rd Edition), which provides a brief introduction to C++20 features. In the book, he shows how export module can eliminate the traditional pattern of having to split declarations and definitions into separate header (.h) and source (.cpp) files. In his book, he introduces a home-brewed vector class module to explain his point:

export module Vector; // defining the module called "Vector"

export class Vector {
public:
    Vector(int s);
    double& operator[](int i);
    int size();
private:
    double* elem; // elem points to an array of sz doubles
    int sz;
};

export bool operator==(const Vector& v1, const Vector& v2) {
    if (v1.size() != v2.size()) 
        return false;
    for (int i = 0; i < v1.size(); ++i) {
        if (v1[i] != v2[i]) 
            return false;
    }
    return true;
}

//Implementations; Supposed to be hidden
Vector::Vector(int s) : elem{new double[s]}, sz{s} {}
double& Vector::operator[](int i) { return elem[i]; }
int Vector::size() { return sz; }

Traditionally, we had to separate header files to expose function signatures (so that consumers of our library know how to call them) and .cpp files to hide implementations. However, with modules, it looks like everything sits in the same file.

My question is: How does having export in a single module file actually hide the implementation from library users? If the implementation is in the same file as the interface, doesn’t that let users (or any consuming compiler) "see" everything by simply looking into the module file?

To put it another way, if I place everything (both the public interface and private implementation) in a single module file, how do I actually hide my private code from clients, while notifying human developers of its function signature, declaration, etc. Isn't text-based header file still needed? I’m specifically concerned about the practical distribution of a closed-source library.


Solution

  • It is important to note that "hide" is normally intended with the sense of avoiding the user "depending" on implementation detais, not neccessarily avoiding the details to be visible.

    If you need a module to be distributed without the verbatim implementation details, indeed you cannot use a single file to put both the closed information and the interface. This solution is intented for a different use case.

    In other words, you may use this feature, which also means you may not use it.