Overloaded function is not found
08:45 05 Feb 2026

I am following the example from the book professional cpp 5ed, ch9.
I have a .ixx file with a member swap function taking 1 argument, and a non-member function taking 2.

export module Spreadsheet;
export import SpreadsheetCell;

export class Spreadsheet
{
public:
    Spreadsheet(size_t width, size_t height);
    Spreadsheet(const Spreadsheet& src);
    Spreadsheet(Spreadsheet&& src) noexcept; 
    ~Spreadsheet();

    Spreadsheet& operator=(const Spreadsheet& rhs);
    Spreadsheet& operator=(Spreadsheet&& rhs) noexcept; 

    void setCellAt(size_t x, size_t y, const SpreadsheetCell& cell);
    SpreadsheetCell& getCellAt(size_t x, size_t y);

    void swap(Spreadsheet& other) noexcept;

private:
    void verifyCoordinate(size_t x, size_t y) const;

    size_t m_width{ 0 };
    size_t m_height{ 0 };
    SpreadsheetCell** m_cells{ nullptr };
};

export void swap(Spreadsheet& first, Spreadsheet& second) noexcept;

Here are their implementations in the .cpp file:

void Spreadsheet::swap(Spreadsheet& other) noexcept
{
    std::swap(m_width, other.m_width);
    std::swap(m_height, other.m_height);
    std::swap(m_cells, other.m_cells);
}

void swap(Spreadsheet& first, Spreadsheet& second) noexcept
{
    first.swap(second);
}

The book recommends implementing move constructor and move assign through swap, like so:

// Move constructor
Spreadsheet::Spreadsheet(Spreadsheet&& src) noexcept
{
    cout << "Move constructor" << endl;

    swap(*this, src);
}

// Move assignment operator
Spreadsheet& Spreadsheet::operator=(Spreadsheet&& rhs) noexcept
{
    cout << "Move assignment operator" << endl;

    swap(*this, rhs);
    return *this;
}

However, my visual studio doesn't see the exported non-member function swap that takes 2 parameters. It gives me E0140 too many arguments in function call, C2660 'Spreadsheet::swap' function does not take 2 arguments, and the intellisense overload list for swap is empty.

error in visual studio

So my questions are:

  1. is it a bug in visual studio, or am i blind and missing something? I thought the exported non-member would be treated like a regular overloaded function, and i can't understand why compiler is not seeing it.

  2. Why are we using the non-member function for it in the first place? Omitting it and using swap(rhs); instead of swap(*this, rhs); seems to work, so why would it be recommended to do it the other way?

Im using VS2022(v143), c++ standard set to latest features

c++ visual-studio overloading