 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Alex Vinokur Guest
|
Posted: Mon Jul 14, 2003 6:12 pm Post subject: Template virtual member method is not allowed. How to bypass |
|
|
=========================================
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
|
Posted: Mon Jul 14, 2003 6:53 pm Post subject: Re: Template virtual member method is not allowed. How to by |
|
|
"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: | 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
|
Posted: Mon Oct 06, 2003 4:34 pm Post subject: Re: Template virtual member method is not allowed. How to by |
|
|
"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.
=======================================
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 |
|
 |
|
|
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
|
|