C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Template virtual member method is not allowed. How to bypass

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Alex Vinokur
Guest





PostPosted: Mon Jul 14, 2003 6:12 pm    Post subject: Template virtual member method is not allowed. How to bypass Reply with quote



=========================================
Windows 2000
CYGWIN_NT-5.0 1.3.22(0.78/3/2)
GNU gcc version 3.2 20020927 (prerelease)
=========================================


Here is some program which is compiled and works fine.

############################################
====== C++ code : File t1.cpp : BEGIN ======
#include <iostream>
using namespace std;

class BBB
{
public :
void foo1 (int n);

protected :
virtual void foo2(int n) = 0;
};

class DDD : public BBB
{
public :
void foo2(int n);
};

void BBB::foo1 (int n)
{
cout << __PRETTY_FUNCTION__ << " : n = " << n << endl;
foo2(n);
}

void DDD::foo2 (int n)
{
cout << __PRETTY_FUNCTION__ << " : n = " << n << endl;
}


int main ()
{
DDD d;
d.foo1(123);
return 0;
}
====== C++ code : File t1.cpp : END ========


====== Compilation & Run : BEGIN ======

$ g++ t1.cpp

void BBB::foo1(int) : n = 123
virtual void DDD::foo2(int) : n = 123

====== Compilation & Run : END ========



I need something like with template virtual member method.
But template virtual member method is not allowed.

############################################
====== C++ code : File t2.cpp : BEGIN ======

#include using namespace std;

class BBB
{
public :
template <typename T>
void foo1 (const T& t);

protected :
template <typename T>
virtual void foo2(const T& t) = 0; // (Line#12) ILLEGAL because template virtual member method is not allowed
};

class DDD : public BBB
{
public :
template <typename T>
void foo2(const T& t);
};

template <typename T>
void BBB::foo1 (const T& t)
{
cout << __PRETTY_FUNCTION__ << " : t = " << t << endl;
foo2(t);
}

template void DDD::foo2 (const T& t)
{
cout << __PRETTY_FUNCTION__ << " : t = " << t << endl;
}


int main ()
{
DDD d;
d.foo1(123);
return 0;
}

====== C++ code : File t2.cpp : END ========


====== Compilation : BEGIN ======

$ g++ t2.cpp

t2.cpp:12: invalid use of `virtual' in template declaration of `virtual void
BBB::foo2(const T&)'

====== Compilation : END ========


Question.
Is there any bypass to get what I want to ?


Thanks,

==========================================
Alex Vinokur
mailto:alexvn (AT) connect (DOT) to
http://www.simtel.net/pub/oth/19088.html
http://sourceforge.net/users/alexvn
==========================================




Back to top
Victor Bazarov
Guest





PostPosted: Mon Jul 14, 2003 6:53 pm    Post subject: Re: Template virtual member method is not allowed. How to by Reply with quote



"Alex Vinokur" <alexvn (AT) bigfoot (DOT) com> wrote...
Quote:
[.. example of polymorphism in its simplest use..]

I need something like with template virtual member method.

Why do you think you need that?

Quote:
But template virtual member method is not allowed.

No, it's not. That's correct.

Quote:

############################################
====== C++ code : File t2.cpp : BEGIN ======

#include using namespace std;

class BBB
{
public :
template void foo1 (const T& t);

protected :
template virtual void foo2(const T& t) = 0; // (Line#12) ILLEGAL because
template virtual member method is not allowed


Yes. You probably want to make the entire class a template,
or have a nested [helper] class, which should be a template.
Template classes can have virtual functions.

Quote:
};

[...]

Quote:
Question.
Is there any bypass to get what I want to ?

No, there is no "bypass" of what is disallowed. But there are
other ways. If you could just tell us what you need that for,
perhaps we could suggest a solution. Try not to phrase your
inquiries "the language doesn't let me do this, how do I do this?"

Victor



Back to top
Alex Vinokur
Guest





PostPosted: Mon Oct 06, 2003 4:34 pm    Post subject: Re: Template virtual member method is not allowed. How to by Reply with quote




"Victor Bazarov" <v.Abazarov (AT) attAbi (DOT) com> wrote

Quote:
"Alex Vinokur" <alexvn (AT) bigfoot (DOT) com> wrote...
[.. example of polymorphism in its simplest use..]

I need something like with template virtual member method.

Why do you think you need that?

But template virtual member method is not allowed.

No, it's not. That's correct.


############################################
====== C++ code : File t2.cpp : BEGIN ======

#include <iostream
using namespace std;

class BBB
{
public :
template void foo1 (const T& t);

protected :
template virtual void foo2(const T& t) = 0; // (Line#12) ILLEGAL because
template virtual member method is not allowed

Yes. You probably want to make the entire class a template,
or have a nested [helper] class, which should be a template.
Template classes can have virtual functions.

};

[...]

Question.
Is there any bypass to get what I want to ?

No, there is no "bypass" of what is disallowed. But there are other ways.

One of such ways are proposed below.
Of course, this approach doesn't solve the problem of disallowance of template virtual member method.
Perhaps it will be useful in certain situations.

Quote:
If you could just tell us what you need that for,
perhaps we could suggest a solution. Try not to phrase your
inquiries "the language doesn't let me do this, how do I do this?"

You are right. The wording is ambiguous.

Quote:

Victor



=======================================
GNU g++ version 3.3.1 (cygming special)
=======================================


========= C++ code : File t.cpp : BEGIN =========
#include #include <sstream>
#include <iostream>
#include <iomanip>
#include <map>
#include <typeinfo>
#include <assert.h>
using namespace std;

#ifdef __GNUC__
#define FUNC_NAME __PRETTY_FUNCTION__
#else
#define FUNC_NAME ""
#endif

#define COUT
cout << "[ "
<< __FILE__
<< ", #"
<< setw(3)
<< std::right
<< __LINE__
<< " ] "
<< FUNC_NAME
<< " : "


// ---------------------
// ---------------------
template bool stream_cast (const From& from, To& to)
{
stringstream stream;
stream << from;
return (stream >> to);
}


// ---------------------
struct AuxTypenames
{
friend bool operator< (const AuxTypenames& ins1_i, const AuxTypenames& ins2_i);

string class_typename_;
string arg_typename_;

AuxTypenames (
const string& class_typename_i,
const string& arg_typename_i
)
:
class_typename_ (class_typename_i),
arg_typename_ (arg_typename_i)
{}
};

// ---------------------
bool operator< (const AuxTypenames& ins1_i, const AuxTypenames& ins2_i)
{
if (ins1_i.class_typename_ < ins2_i.class_typename_) return true;
if (ins1_i.class_typename_ > ins2_i.class_typename_) return false;

return (ins1_i.arg_typename_ < ins2_i.arg_typename_);
}



// ---------------------
// ---------------------
class Boo;


// ---------------------
class AuxBaseCaller
{
public :
virtual bool caller(Boo* ptr_io, const string& str_i) = 0;
};


template class AuxCaller : public AuxBaseCaller
{
public :
bool caller(Boo* ptr_io, const string& str_i);
};



// ---------------------
template <typename T1, typename T2>
bool AuxCaller<T1, T2>::caller(Boo* ptr_io, const string& str_i)
{
T2 data;

if (!stream_cast (str_i, data))
{
COUT << "Unable to do stream_cast : "
<< typeid(str_i).name()
<< " to "
<< typeid(data).name()
<< "; From-string-value = <"
<< str_i
<< ">"
<< endl;

return false;
}

T1* ptr = dynamic_cast assert (!(ptr == NULL));

ptr->foo2 (data);

return true;
}


// ---------------------
// ---------------------
class Boo
{
protected :
void bridge (const string& arg_typename_i, const string& str_i);

public :
static map<AuxTypenames, AuxBaseCaller*> callers_s;

virtual ~Boo () {}

template <typename T>
void foo1 (const T& t);

};

// ---------------------
class Dxx : public Boo
{
template <typename T1, typename T2> friend class AuxCaller;

private :
template <typename T>
void foo2(const T& t) { COUT << "t = " << t << endl; }
};


// ---------------------
class Dyy : public Boo
{
template
private :
template <typename T>
void foo2(const T& t) { COUT << "t = " << t << endl; }
};


// ---------------------
class Dzz : public Boo
{
template
private :
template <typename T>
void foo2(const T& t) { COUT << "t = " << t << endl; }
};



// ---------------------
// ---------------------
template void Boo::foo1 (const T& data_i)
{
COUT << "data_i = " << data_i << endl;

string str;
if (!stream_cast (data_i, str))
{
COUT << "Unable to do stream_cast : "
<< typeid(data_i).name()
<< " to "
<< typeid(str).name()
<< "; From-T-value = <"
<< data_i
<< ">"
<< endl;

return;
}

bridge(typeid(data_i).name(), str);
}


// ---------------------
void Boo::bridge (const string& arg_typename_i, const string& str_i)
{
COUT << "arg_typename_i = " << arg_typename_i << endl;

assert (!callers_s.empty());
const string class_typename (typeid(*this).name());
const map
if (find_iter == callers_s.end())
{
COUT << ""
<< "Pair (class typename = "
<< class_typename
<< ", arg typename = "
<< arg_typename_i
<< ") is not allowed"
<< endl;
return;
}

assert (find_iter != callers_s.end());

if (!find_iter->second->caller(this, str_i)) assert (0);

}


// ---------------------
// ---------------------
map<AuxTypenames, AuxBaseCaller*> Boo::callers_s;

#define ADD_CALLER(T1, T2)
Boo::callers_s[AuxTypenames (typeid(T1).name(), typeid(T2).name())] =
static_cast<AuxBaseCaller*> (new AuxCaller<T1, T2> ())


// ---------------------
int main ()
{
ADD_CALLER (Dxx, int);
ADD_CALLER (Dxx, char);
ADD_CALLER (Dxx, float);

ADD_CALLER (Dyy, int);
ADD_CALLER (Dyy, char);

// ---------------------
Dxx dxx;
cout << endl;
cout << endl;
cout << "t--- Dxx test ---" << endl;

dxx.foo1(100);
cout << endl;
dxx.foo1(char('a'));
cout << endl;
dxx.foo1(float (3.14));


Dyy dyy;
cout << endl;
cout << endl;
cout << "t--- Dyy test ---" << endl;

dyy.foo1(200);
cout << endl;
dyy.foo1(char('b'));
cout << endl;
dyy.foo1(float (2.71));


Dzz dzz;
cout << endl;
cout << endl;
cout << "t--- Dzz test ---" << endl;

dzz.foo1(300);

// -----
return 0;
}

========= C++ code : File t.cpp : END ===========

Two remarks.
1. stream_cast() was discussed by Dietmar Kuehl at
http://groups.google.com/groups?selm=8kk8tk%2470m%241%40nnrp1.deja.com

2. To be sure the stream_cast conversion is bijective, one could use functions which detect stream_cast bijectivity
http://groups.google.com/groups?th=8bb967e46c5e3a87



========= Compilation & Run : BEGIN =========

$ g++ t.cpp

$ a

--- Dxx test ---
[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = int] : data_i = 100
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = i
[ t.cpp, #143 ] void Dxx::foo2(const T&) [with T = int] : t = 100

[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = char] : data_i = a
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = c
[ t.cpp, #143 ] void Dxx::foo2(const T&) [with T = char] : t = a

[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = float] : data_i = 3.14
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = f
[ t.cpp, #143 ] void Dxx::foo2(const T&) [with T = float] : t = 3.14


--- Dyy test ---
[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = int] : data_i = 200
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = i
[ t.cpp, #154 ] void Dyy::foo2(const T&) [with T = int] : t = 200

[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = char] : data_i = b
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = c
[ t.cpp, #154 ] void Dyy::foo2(const T&) [with T = char] : t = b

[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = float] : data_i = 2.71
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = f
[ t.cpp, #207 ] void Boo::bridge(const std::string&, const std::string&) : Pair (class typename = 3Dyy, arg typename = f) is not
allowed


--- Dzz test ---
[ t.cpp, #175 ] void Boo::foo1(const T&) [with T = int] : data_i = 300
[ t.cpp, #199 ] void Boo::bridge(const std::string&, const std::string&) : arg_typename_i = i
[ t.cpp, #207 ] void Boo::bridge(const std::string&, const std::string&) : Pair (class typename = 3Dzz, arg typename = i) is not
allowed

========= Compilation & Run : END ===========


=====================================
Alex Vinokur
mailto:alexvn (AT) connect (DOT) to
http://mathforum.org/library/view/10978.html
=====================================





Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.