views:

87

answers:

3

Hi there. I'm currently building a set of common functions (Search algorithm implementations), and think I'm doing the grouping wrong. At the moment, I have a class, Sorting, that is declared in a file called Sorting.h (it's nowhere near finished yet, btw) like so:

#ifndef SORTING_H
#define SORTING_H

#include <vector>

class Sorting {

private:
    Sorting();
    Sorting(const Sorting& orig);
    virtual ~Sorting();

public:
    static void bubbleSort(std::vector<int>& A);
    // etc
};

#endif  /* SORTING_H */

Now, because the constructor is private, a user cannot instantiate my class - it effectively is just a holder for static functions that the user can call. However, from what I have read of C++ so far - and from looking at the STL libraries etc- I think I'm doing this wrong. Should I instead have a namespace called 'Sorting' or something of the sort? If so, what does my header file (the one the user would include) look like? And would I have to change the structure of the rest of the files? At the moment each set of algorithms is in it's own cpp file (i.e. BubbleSort.cpp, CocktailSort.cpp, etc).

Apologies for what may be a duplicate question - I did search for C++ and namespace, but I got very general questions about namespaces back and none seemed to be this specific problem.

+1  A: 

It doesn't matter, a free function in a namespace achieves the same. The syntax for calling it is identical.

Hans Passant
A: 

I'll recomend using a namespace if the class is not to be instantiated.

Code Clown
+3  A: 

Use a namespace. The callers of the code won't need to care. Also, you need to template on any sortable type- a sort that can only sort a vector of integers is rather bad. Stick to the definition provided by std::sort.

namespace Sorting {
    template<typename Iterator> void cocktail_sort(Iterator a, Iterator b) {
        // implement cocktail sort
    }
    template<typename Iterator> void bubble_sort(Iterator a, Iterator b) {
        // implement bubble sort
    }
};

The caller won't care whether you're statically in a class, but the simple fact is that you waste semantics and time having it in a class, and it doesn't accurately represent the intention. It's not wrong, per se, but it is kinda bad. Using a namespace also allows callers to use the using namespace Sorting; semantics.

DeadMG
`(Iterator first, Iterator last)`, for illustration.
Potatoswatter
Thanks. I'm going to move to templates soon, I was just trying to find out how you tell if a templated class/primitive is comparable in C++ - i.e. how do I know that it will work when "<" etc is called on it. Or is that something the end user should be worried about? As another question - here you have put cocktail_sort and bubble_sort in the same namespace declaration - can I use multiple separate files for this?
Stephen
@DeadMG: Two suggestions: 1. The type names usually describe the kind of iterators required, e.g. `RandomAccessReadableWriteableIterator` or `ForwardReadableWriteableIterator`. 2. As an alternative to iterators, you could use ranges, which are more flexible and easier to use.
Philipp
@Philipp: I know. I just forgot what kind of iterator std::sort takes. As for ranges, I have nothing *against* ranges- but everyone else uses iterators and you're begging for doom not sorting on iterators. The easiest way to get your code used is to mimic the STL, including it's flaws. @Stephen: You don't know, it's the users problem. Secondly, you can't use any .cpp files- templated classes/functions all have to have their full definition available to be used. The namespace declaration is irrelevant to this fact.
DeadMG
@Stephen: Currently there are no concepts checks in the C++ language. You can either use Boost.Concept or just document the concept requirements ("`iterator_traits<Iterator>::value_type` must be `LessThanComparable`, and the comparison must induce a strict weak ordering relation"). And yes, you can use multiple implementation files. You can even use multiple *header* files, something that is not possible with classes. Take the `std` namespace—it is implemented in hundreds of header and implementation files.
Philipp
@Philipp: Not for any functions that are templated. No .cpp files there.
DeadMG
... DeadMG says I can't use implementation (.cpp) files, Philipp says I can. Have I misunderstood one of you, or is one of you... well, wrong?
Stephen
@Stephen: Try it.
DeadMG
DeadMG is right. You can't use .cpp files for templated functions. (But you can use them for non-templated functions, and then you can use many of them for a single namespace.) Actually I just wasn't careful enough. You can put the original function `void bubbleSort(std::vector<int>` in an implementation file, but not the suggestions made by DeadMG (which are correct, after all).
Philipp