Skip to main content
GameDev.net gamedev.net
🔒 Locked

Anyone have a work around?

Started by Null and Void Apr 24, 2002 at 10:59 PM 5 replies 3.6k views
Original Post
Null and Void
Null and Void
The following legal code doesn''t work and is known to not work in MSVC 6:
  
#include <iostream>

class inner_base {
	public:
		virtual void output(void) = 0;
};

class inner_a : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_a" << std::endl; }
};

class inner_b : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_b" << std::endl; }
};

class outer {
	private:
		inner_base *my_inner;
	public:
		template <class T>
		inline void create_inner(void) {
			delete my_inner;
			my_inner = new T;
		}
		inline void output(void) {
			if(my_inner) my_inner->output();
		}

		outer(void) : my_inner(NULL) { }
		~outer(void) { delete my_inner; }
};

int main(void) {
	outer my_outer;

	// MSVC 6''s deficiency comes up right here

	my_outer.create_inner<inner_b>();
	my_outer.output();

	return 0;
}
  
Does anyone have a simple work around to make this work in MSVC 6? The optimal solution would look the most like that code. If I can''t get that kind of thing to work somehow I''ll have to drop support of MSVC 6, and many Windows (co-)developers might not like that. The two best (but obviously lacking) workarounds I''ve come up with so far:
  #include <iostream>

class inner_base {
	public:
		virtual void output(void) = 0;
};

class inner_a : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_a" << std::endl; }
		static inline inner_base *spawn(void) { return (inner_base *) new inner_a; }
};

class inner_b : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_b" << std::endl; }
		static inline inner_base *spawn(void) { return (inner_base *) new inner_b; }
};

class outer {
	private:
		inner_base *my_inner;
	public:
		template <class T>
		inline void create_inner(T spawn) {
			delete my_inner;
			my_inner = spawn();
		}
		inline void output(void) {
			if(my_inner) my_inner->output();
		}

		outer(void) : my_inner(NULL) { }
		~outer(void) { delete my_inner; }
};

int main(void) {
	outer my_outer;

	my_outer.create_inner(&inner_b::spawn);
	my_outer.output();

	return 0;
}
  

  
#include <iostream>

class inner_base {
	public:
		virtual void output(void) = 0;
};

class inner_a : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_a" << std::endl; }
};

class inner_b : public inner_base {
	public:
		virtual void output(void) { std::cout << "inner_b" << std::endl; }
};

class outer {
	private:
		inner_base *my_inner;
	public:
		template <class T>
		inline void create_inner(const T _T) {
			delete my_inner;
			my_inner = new T;
		}
		inline void output(void) {
			if(my_inner) my_inner->output();
		}

		outer(void) : my_inner(NULL) { }
		~outer(void) { delete my_inner; }
};

int main(void) {
	outer my_outer;

	my_outer.create_inner(inner_b());
	my_outer.output();

	return 0;
}
  
So, what''s your suggestion?
daerid
daerid
Templated members don''t work with VC++

as to the question, no clue
daerid@gmail.com
elis-cool
elis-cool
Is this fixed in VC++.NET

CEO Plunder Studios
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
Null and Void
Null and Void
quote:
Original post by elis-cool
Is this fixed in VC++.NET

Probably, but I don''t know. I know it works in even older versions of GCC, so I''d hope so.

DrPizza
DrPizza
The second workaround doesn''t seem all that lacking. Alternatively, require VS.NET.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;} /*** drpizza@battleaxe.net ***/
Void
Void
Use an templated struct indirection.

From Modern C++ Design, pass a dummy Type2type as a parameter

There may be other way to avoid the parameter, but it''s all about using a templated struct instead of templated functions.


  
#include <iostream>

class inner_base
{
public:
virtual void output() = 0;
};

class inner_a : public inner_base
{
public:
virtual void output()
{
std::cout << "inner_a" << std::endl;
}
};

class inner_b : public inner_base
{
public:
virtual void output()
{
std::cout << "inner_b" << std::endl;
}
};

// From modern C++ Design

template <class T>
struct Type2Type
{
typedef T type;
};

class outer
{
private:
inner_base *my_inner;
public:

outer(void) : my_inner(NULL)
{}

~outer(void)
{
delete my_inner;
}

template <class T>
inline void create_inner( Type2Type<T> )
{
delete my_inner; my_inner = new T;
}

inline void output()
{
if(my_inner)
my_inner->output();
}

};

int main(void)
{
outer my_outer;

// MSVC 6''s deficiency comes up right here


my_outer.create_inner( Type2Type<inner_b>() );
my_outer.output();

return 0;
}
Null and Void
Null and Void
The reason I said my work arounds were lacking is that I was actually passing data in the parameter, which shouldn''t really be necessary in this solution. I''m really trying to avoid only targeting VS .NET (which not many people own) and GCC (which not many people use in Windows). I like your solution Void, I think I''ll go with it, since it doesn''t hurt GCC any but it still works in MSVC 6.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.