Jump to content
  • Advertisement
Sign in to follow this  
hogwash

nameless struct/union inside template class

This topic is 5400 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Guys, I have a bit of problem that I hope you can help me with:
template <typename T>
class Foo
{
public:
	T x;
	T y;
};

template <typename T, class C>
class Bar
{
public:
	union
	{
		struct : public C
		{
		};
		T xy[2];
	};
};
int main()
{
	Bar<float, Foo<float> > bar;
	float test = bar.x;

	return 0;
}


I get the following error in VS.NET 2003
Quote:
\warroom\Maths\Source\Test.cpp(28): error C2039: 'x' : is not a member of 'Bar<T,C>' with [ T=float, C=Foo<float> ]
The question basically is- Can I have a nameless struct derived from a templated class?? Cheers, Tom. [Edited by - hogwash on October 5, 2004 6:42:46 PM]

Share this post


Link to post
Share on other sites
Advertisement
Nameless structs that are not used to declare variables are not part of standard C++, but some compilers will allow them in some ways.

Share this post


Link to post
Share on other sites
As I understood it, nameless structs/unions are a Microsoft extension that should be supported in their current gen compiler. Any ideas why this code may not work (apart from lack of compiler support, because this should be a non-issue in my situation)?

Thanks,

Tom

Share this post


Link to post
Share on other sites
Just thought I would mention- the following works fine for me:

template <typename T>
class Bar
{
public:
union
{
struct
{
float x;
float y;
};
T xy[2];
};
};
int main()
{
Bar<float, Foo<float> > bar;
float test = bar.x;

return 0;
}


... the thing is I want to be able to pass in the contents of the nameless struct as a template argument...

Share this post


Link to post
Share on other sites
Quote:
Original post by hogwash
Just thought I would mention- the following works fine for me:

*** Source Snippet Removed ***

... the thing is I want to be able to pass in the contents of the nameless struct as a template argument...
That code snippet will work on some compilers, but it isn't standards compliant C++ and isn't guaranteed to work.

Share this post


Link to post
Share on other sites
This works, your compiling is having trouble with the name resolution because of the anonymous struct. The using statement gives a nice fat hint to the name resolution.

struct : public C
{
using C::x;
using C::y;
};

Share this post


Link to post
Share on other sites
That kind of defeats the purpose of why I am passing in that class as a template argument- it is so I can keep the contents of that struct completely encapsulated in a seperate class... oh well back to the drawing board - thanks for the responses so far.

Share this post


Link to post
Share on other sites
another problem with unions is you can't initialize memembers in a constructor initiailizer list, here is a much better & standard compliant alternative you can also use constructor initializer lists with it:


#include <cstddef>
#include <iostream>

template< typename T >
struct Vector4 {

typedef size_t size_type;
typedef T Vector4<T>::* const vec[4];

private:

static const vec v;

public:

T x, y, z, w;

Vector4(T _x = 0, T _y = 0, T _z = 0, T _w = 0):
x(_x), y(_y), z(_z), w(_w) {}

const T& operator[](size_type i) const {
return this->*v;
}

T& operator[](size_type i) {
return this->*v;
}

};

template< typename T >
const typename Vector4<T>::vec Vector4<T>::v = { &Vector4<T>::x, &Vector4<T>::y, &Vector4<T>::z, &Vector4<T>::w };

template< typename T >
struct matrix4 {

typedef size_t size_type;
typedef Vector4<T> matrix4::* const mat[4];

private:

static const mat a;

public:

Vector4<T> i, j, k, l;

matrix4(const Vector4<T>& _i = Vector4<T>(),
const Vector4<T>& _j = Vector4<T>(),
const Vector4<T>& _k = Vector4<T>(),
const Vector4<T>& _l = Vector4<T>())
: i(_i), j(_j), k(_k), l(_l) {}

const Vector4<T>& operator[](size_type i) const {
return this->*a;
}

Vector4<T>& operator[](size_type i) {
return this->*a;
}
};

template< typename T >
const typename matrix4<T>::mat matrix4<T>::a = { &matrix4<T>::i, &matrix4<T>::j, &matrix4<T>::k, &matrix4<T>::l };

int main() {

matrix4<int> m;

m[0][0] = 10;

std::cout << "m[0][0]: " << m[0][0] << '\n';
std::cout << "m[0].x: " << m[0].x << '\n';
std::cout << "m.i.x: " << m.i.x << '\n';

return 0;

}


[Edited by - snk_kid on October 7, 2004 9:21:55 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by hogwash
That kind of defeats the purpose of why I am passing in that class as a template argument- it is so I can keep the contents of that struct completely encapsulated in a seperate class... oh well back to the drawing board - thanks for the responses so far.

It doesn't break encapsulation any more than you do anyway by providing access to elements of C through the union. In order to make use of the x and y elements of C you *need* to know that there is an x and y in the first place. The extra using statements don't require any information that you don't already know and therefore you aren't breaking encapsulation (any further, anyway).

Share this post


Link to post
Share on other sites
Quote:

/*...*/

template< typename T >
const typename Vector4<T>::vec Vector4<T>::v = { &Vector4<T>::x, &Vector4<T>::y, &Vector4<T>::z, &Vector4<T>::z };

/*...*/


I think you mean to have ::w as the last element there.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!