Thread: General Purpose Operator Overloading

  1. #1
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308

    General Purpose Operator Overloading

    I haven't been able to practice programming for a few months now and have lost my ability (whatever little I had) to understand templated code. I'm trying to write a general purpose operator overload that works for C++ containers (for example, an overload to output its contents). This is what I have right now:

    Code:
    template <template <typename...> typename Container, typename T, typename... A>
    ostream& operator << (ostream& os, const Container <T, A...>& c) {
        os << __PRETTY_FUNCTION__ << '\n';
        for (const auto& i : c) {
            os << i << ' ';
        }
        return os;
    }
    However, this only kinda works if I use:

    Code:
        std::vector <int> v {1, 2, 3, 4};
        std::cout << v << '\n';
    I'd like this to also work for std::map, let's say. But trying to do so throws me a bunch of errors (as I'd expected). std::ostream doesn't yet have an overload for std::pair, which is what gets used when using iterators on map, and so I need to define what it should do with pair.

    Code:
        std::map <int, std::string> m {{1, "abcde"}, {2, "abcd"}, {3, "acde"}, {4, "ade"}};
        std::cout << m << '\n';
    In hopes of getting rid of the error, I define something like this:

    Code:
    template <typename A, typename B> std::ostream& operator << (std::ostream& os, const std::pair <A, B>& p) {
        return os << '(' << p.first << ", " << p.second << ')';
    }
    This leads to ambiguity errors, which I understand why it happens but don't know how to fix. Any help regarding "Writing a general purpose overload for STL containers" will be appreciated. Thank you.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    I feel that unless you're maintaining a library and hence can freely add to its namespace, you probably shouldn't add operators to its interface. The reason is that you're dependent on argument dependent lookup, which means that the operator will be searched for in the namespaces of its arguments. If you're overloading operator<< for output streams, one of these namespaces will be the std namespace, but the other would be the output object's namespace (which could also be the std namespace, in the case of standard containers), not your own namespace. So, you will have to pollute the global namespace with this operator so that it will be found by name lookup. Consequently, it may be better to provide a named function within your namespace to do the job, hence making it natural for the function to be qualified by namespace name (which you admittedly can do with an operator, but it defeats the purpose of providing an operator).

    As for the ambiguity issue: it may be non-trivial to fix. The problem seems to be that the type const Container <T, A...>& is so generic that it is matching stuff that you don't want it to match, e.g., things that aren't really containers in the sense that you have in mind. If you really want to go ahead with the operator overloading, then my suggestion would be to overload separately for each container type that you want to have such functionality.
    Last edited by laserlight; 09-17-2020 at 05:17 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    Understood, thanks! I'm just playing around with code that I'll probably never use in hopes of trying to improve my understanding of templates and get more familiar with them.

    Are there any good practice exercises you'd have in mind related to complicated template usage?
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What is the main purpose of operator overloading
    By sigur47 in forum C++ Programming
    Replies: 3
    Last Post: 02-03-2012, 09:32 AM
  2. Help with Operator Overloading
    By Swerve in forum C++ Programming
    Replies: 6
    Last Post: 10-23-2009, 11:01 PM
  3. Purpose of Operator Overloading
    By xmltorrent in forum C++ Programming
    Replies: 11
    Last Post: 08-09-2006, 06:23 PM
  4. Operator overloading example...
    By Dan17 in forum C++ Programming
    Replies: 4
    Last Post: 02-22-2006, 02:47 PM
  5. Purpose of Overloading Operators
    By luckygold6 in forum C++ Programming
    Replies: 3
    Last Post: 02-28-2003, 09:14 PM

Tags for this Thread