K
Kai-Uwe Bux
Ben said:Kai-Uwe Bux said:I ran into the ADL
issue myself when I defined operator<< for all the standard containers.
As far as I know, putting them within namespace std is not permitted
because they lack dependence "on a user-defined name of external
linkage". And yes, ADL caused problems for me in this case.
I think this is fair though. In your case (within one particular
program), a stream operator for the standard containers might make
sense, but surely in general, it doesn't make sense.
The solution would be to define your own type, and the stream operator
for that. Obviously a typedef doesn't suffice - is the only solution to
wrap the container to produce your own type?
#include <vector>
#include <iostream>
#include <ios>
//#define OWNTYPE
#ifndef OWNTYPE
typedef std::vector<int> myType;
#else
class myType {
typedef std::vector<int> type;
type vec_;
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator begin() const { return vec_.begin(); }
const_iterator end() const { return vec_.end(); }
myType(type::size_type count, const type::value_type& val) :
vec_(count, val) {};
type::value_type operator[](const type::size_type index) {
return vec_[index];
}
//etc.
};
#endif
std:stream& operator<<(std:stream& lhs, const myType& rhs) {
for (myType::const_iterator iter = rhs.begin(); iter != rhs.end();
++iter) {
lhs << *iter << "\n";
}
return lhs;
}
int main()
{
std::vector<int> v1(2,6);
myType v2(2,7);
#ifndef OWNTYPE
std::cout << v1 << std::endl;
#endif
std::cout << v2 << std::endl;
}
That's a lot of hassle.
Ok, I had a closer look at your solution. It seems that you want to create a
different type for this std::vector<int> so that the C++ overloading
mechanism will handle things gracefully. I would suggest to just inherit
like so:
template < typename T >
struct math_vector : public std::vector< T > {
math_vector ( void )
: std::vector< T > ()
{}
template < typename A >
math_vector ( A a )
: std::vector< T > ( a )
{}
template < typename A, typename B >
math_vector ( A a, B b )
: std::vector< T > ( a, b )
{}
template < typename A, typename B, typename C >
math_vector ( A a, B b, C c )
: std::vector< T > ( a, b, c )
{}
template < typename A, typename B, typename C, typename D >
math_vector ( A a, B b, C c, D d )
: std::vector< T > ( a, b, c, d )
{}
}; // math_vector<>
Now, math_vector<int> and std::vector<int> are distinct types whose
interfaces are completely identical.
I used that to define arithmetic operators for vectors in my math programs
so that they would not apply to vectors that are just data structures.
Best
Kai-Uwe Bux