I've got a container that looks like this:
...and would like to be able to do things like this:
"Easy," I think to myself, write a friend operator+:
One of the problems I'm running into may be compiler related: in the class declaration of the friend function (line 25 above), I get an error:
...which confuses me, because I thought this was the correct way to declare friend templates as per the C++ FAQ and the GCC FAQ. But, those examples didn't take multiple template parameters, so maybe something changes.
Another problem that I think I will run into is that I don't know if the friendship mechanism will allow Foo<T>._data and Foo<U>._data to be accessible in the operator+() function. That is my hope, even though Foo<float> and Foo<double> are distinct types. If not, how do I allow such a thing without using a public accessor?
Basically the purpose of this container is to couple a status with a POD. We need a way in our system to flag variables as invalid, and for that status to cascade to any variables that are results of calculations of that invalid variable. We'd still like to treat these variable containers like POD, though, except for special cases during comparisons and extraction of the actual data it contains (needs to be valid, or else it throws... hence public accessor can't be used in operators). The above class is a slight over-simplification, but illustrates the problem.
I'm not sure this is the best way to achieve what I want, or if it's even possible within C++, but I couldn't find any generic containers out there that would allow POD-style operators between containers of compatible PODs. I'm open to suggestions for alternate methods/containers/idioms!
My previous incarnation of this class basically had a byte array, an enumerated identifier that specified the POD type to emulate, a lot of hand-coded operators with switch() statements and conversion constructors. The run-time overhead started to get significant, so I'm trying to re-work as much of the type stuff into compile-time as possible.
OS: GNU/linux
Compiler: gcc 3.4.6
Thanks in advance for any insight!
Code:
template <class T>
class Foo
{
public:
Foo() : _data(), _status(1) { }
Foo(T) : _data(T), _status(0) { }
~Foo() { }
template<class U>
Foo<T>& operator=(const U& u) {_data=u; _status=0; return *this;}
private:
T _data;
int _status;
};
Code:
Foo<float> fooF(3.5); Foo<double> fooD1(4.7); Foo<double> fooD2=fooF+fooD1;
Code:
[B]
//gcc typeof(T()+U()) results in an ICE... this is my work-around
template <class T, class U>
struct Promote
{
static const T t;
static const U u;
typedef typeof(t+u) Result;
};
[/B]
[B]template <class T> Foo; //forward declaration of class Foo[/B]
[B]template <class T, class U> Foo<typename Promote<T,U>::Result> operator+(const Foo<T>& lhs, const Foo<U>& rhs); //identify operator+ as template func[/B]
template <class T>
class Foo
{
public:
Foo() : _data(), _status(1) { }
Foo(T) : _data(T), _status(0) { }
~Foo() { }
template<class U>
Foo<T> operator=(const U& u) {_data=u; _status=0;}
[B]template <class U>
Foo<typename Promote<T,U>::Result> operator+<>(const Foo<T>& lhs, const Foo<U>& rhs);[/B]
private:
T _data;
int _status;
};
[B]
//operator+() definition
template <class T, class U> Foo<typename Promote<T,U>::Result> operator+(const Foo<T>& lhs, const Foo<U>& rhs)
{
Foo<typeof(lhs._data+rhs._data)> result;
result._data=lhs._data+rhs._data;
result._status=lhs._status|rhs._status;
return result;
}[/B]
Code:
error: invalid use of template-id `operator+<>' in declaration of primary template
Another problem that I think I will run into is that I don't know if the friendship mechanism will allow Foo<T>._data and Foo<U>._data to be accessible in the operator+() function. That is my hope, even though Foo<float> and Foo<double> are distinct types. If not, how do I allow such a thing without using a public accessor?
Basically the purpose of this container is to couple a status with a POD. We need a way in our system to flag variables as invalid, and for that status to cascade to any variables that are results of calculations of that invalid variable. We'd still like to treat these variable containers like POD, though, except for special cases during comparisons and extraction of the actual data it contains (needs to be valid, or else it throws... hence public accessor can't be used in operators). The above class is a slight over-simplification, but illustrates the problem.
I'm not sure this is the best way to achieve what I want, or if it's even possible within C++, but I couldn't find any generic containers out there that would allow POD-style operators between containers of compatible PODs. I'm open to suggestions for alternate methods/containers/idioms!
My previous incarnation of this class basically had a byte array, an enumerated identifier that specified the POD type to emulate, a lot of hand-coded operators with switch() statements and conversion constructors. The run-time overhead started to get significant, so I'm trying to re-work as much of the type stuff into compile-time as possible.
OS: GNU/linux
Compiler: gcc 3.4.6
Thanks in advance for any insight!
Comment