Forward declare a templatized class

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::eek:stream& operator<<(std::eek: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
 
S

Shezan Baig

Kai-Uwe Bux said:
mechanism will handle things gracefully. I would suggest to just inherit
like so:

template < typename T >
struct math_vector : public std::vector< T > {



It is generally a *bad* idea to inherit from standard containers.
Please don't advocate this. See FAQ.


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.



Wrong. There is no math_vector<int>::value_type, for example.

-shez-
 
K

Kai-Uwe Bux

Shezan said:
It is generally a *bad* idea to inherit from standard containers.
Please don't advocate this. See FAQ.

I know about that FAQ. This, however, is one of those recommendations that
have a firm foundation in just one of the various programming paradigms
supported by C++. Namely, if you think OO, then it is a bad idea to inherit
from classes without virtual destructors. The reason is that, sooner or
later, you will find yourself deleting polymorphic pointers to objects in
your class hierarchy.

However, if you think, for instance, policy based design, you will find that
inheriting from classes without virtual destructors is quite common.
Extending advice beyond the scope of applicability is not good. In the case
under discussion (i.e., in the context of math programming), inheriting
from std::vector<> is absolutely fine: there is no use for polymorphic use
of pointers to those objects anyway, and if there was, the same warnings
that apply to std::vector will apply to math_vector. Inheritance, in this
case, is just an implementation detail.

Wrong. There is no math_vector<int>::value_type, for example.

Whereas your statement above is a matter of opinion, this is a matter of
fact. And you got it wrong: math_vector<int>::value_type is there. Just try
it.

#include <vector>

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<>

int main ( void ) {
math_vector<int>::value_type a;
}

compiles without problems. If you think that this is not standard
conformant, please cite chapter and verse.



Best

Kai-Uwe Bux
 
S

Shezan Baig

Kai-Uwe Bux said:
Whereas your statement above is a matter of opinion, this is a matter of
fact. And you got it wrong: math_vector<int>::value_type is there. Just try
it.


You are right, sorry for judging so quickly.

-shez-
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top