Quote:
Also, note that the real std::list offers a much richer interface, but a normal implementation won't involve any kind of 'current' pointer (which also wouldn't be helpful for implementing any of the functions you've shown). Iteration is handled by separate iterator objects.
I wanted to comment that binding implementation of iteration functionality to the list itself (this is what I'd assume "current" is for) is an
extremely bad idea, because then a given list can be iterated only once at a time; attempting to iterate the same list from two different locations (which is possible even in single-threaded contexts) will cause serious problems.
Quote:
I'm not really bothered about using the name list, as only I'm going to use this, so I don't have to worry about confusing anyone.
Wrong. You've posted this code here asking for help, meaning you yourself are no longer its sole consumer. The fully-qualified name for your class (std::list) conflicts with
real std::list. Your code
is not standard, so it should not be in the std namespace. It doesn't matter whether or not you have some kind of stubborn, short-sighted opinion that nobody else will ever see your code (already disproven) or that since it is for your own use you can apply poor software development methodology. Adherance to such doctrine produces bad (as somebody else already mentioned, dailywtf-worthy) developers. Do you really want to do that to yourself?
All you have to do to correct the problem is use your own namespace instead of std so you are not pretending like your code is standard.
I notice, too, that your interface seems very similar to (the real) std::list. Perhaps you have placed yours into the std namespace so you can easily do benchmark tests with the same test harness? This is probably not the greatest idea (it restricts your interface, which may restrict your implementation, which may prevent you from making certain optimizations you could make to become faster than std::list in certain circumstances; for similar reasons it can also bloat your results because you may have achieved faster performance than std::list using its own interface, but in doing so have violated some performance guarantee required of std::list that you didn't know about).
However, the proper way to do that would be:
#if defined(USE_MY_LIST)#include "mylist.h"using my::list;#else#include <list>using std::list;#endifint main(void){list< int > test; /* use list here... */}
Quote:
And the ANSI standard says that Template and function code being separate is fully acceptable, so if the "major ones" all refuse to allow it, that just makes the whole lot of them non ANSI-compliant.
Every compiler out there is ANSI compliant on the separation of template code declaration and definition. This refers only to the ability to do
// declaretemplate< typename T_ > void foo(const T_ &bar);/* ... */// definetemplate< typename T_ > void foo(const T_ &bar){ /* ... */}
that's all. The definition must be available in full to any translation unit that will use the template, prior to the specific use in that translation unit. It
is true that pretty much every compiler out there does not support the "export" keyword, but that's because
1) it's really hard to implement
2) it doesn't actually solve the real problems
so there is precious little reason for anybody to bother supporting it.
The idiomatic solution is to include the implementation file into the header file via the preprocessor #include directive. Note that when doing this, it is usually a good idea to rename the implementation file so that it has a non-standard C++ extension (.inl or .cpp.inl are common). This is because most compilers would still attempt to compile the .cpp file if it is included in the project/makefile/whatever, which will result in all sorts of compile and/or link-time errors.