473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Polymorphism (without virtual functions) with a method template.

Suppose that I want to write a (concrete) interface class (without
virtual functions) to classes that contain a method template

// --------------------------------------
class Interface {
public:
template <typename Wrapped>
Interface(Wrapped& );
// wraps a reference to another object
// that implements the method template

template <typename T>
bool foo(T ); // forwards the call to the wrapped object
};
// --------------------------------------

and then use it:

// --------------------------------------
class Bar {
public:
template <typename T>
bool foo(T );
};

....
Bar b;
Interface i(b);
// --------------------------------------
The problem is that I don't know how to implement this. I know how to
implement it without method templates (with table of function
pointers).

Any idea how to do it?

Thanks.
Dec 11 '07 #1
8 1951
On 11 Pro, 13:58, Belebele <beluc...@gmail.comwrote:
Suppose that I want to write a (concrete) interface class (without
virtual functions) to classes that contain a method template

// --------------------------------------
class Interface {
public:
template <typename Wrapped>
Interface(Wrapped& );
// wraps a reference to another object
// that implements the method template

template <typename T>
bool foo(T ); // forwards the call to the wrapped object};

// --------------------------------------

and then use it:

// --------------------------------------
class Bar {
public:
template <typename T>
bool foo(T );

};

...
Bar b;
Interface i(b);
// --------------------------------------

The problem is that I don't know how to implement this. I know how to
implement it without method templates (with table of function
pointers).

Any idea how to do it?

Thanks.
I am not sure if I understood exactly what you need. If you want to
store value of some templated type, you have to make the whole class
templated (because the Wrapped type and value must be accessible from
constructor as well as from method foo).

// --------------------------------------
template<typename Wrapped>
class Interface {
public:
Interface(Wrapped& w): w_(w) { }
// wraps a reference to another object
// that implements the method template

template <typename T>
bool foo(T& t) // forwards the call to the wrapped object
{
w_.foo(t);
}

private:
Wrapped& w_;
};

// --------------------------------------

and then use it:

// --------------------------------------
class Bar {
public:
template <typename T>
bool foo(T );

};

....
Bar b;
Interface<Bari(b);
// --------------------------------------

Dec 11 '07 #2
I am not sure if I understood exactly what you need. If you want to
store value of some templated type, you have to make the whole class
templated
That's not what I want. I want the Interface class to be a class, not
a class template. That way, I could potentially assign to an object of
the Interface class any object that implements the desired interface.
That is:

class B1 {
public:
template <typename T>
void foo(T );
};

class B2 {
public:
template <typename T>
void foo(T );
};

B1 b1;
Interface i(b1);
i.foo(1);

B2 b2;
i = b2;
i.foo(1);
This is simple to implement if the interface does not contain method
templates. I am lost when method templates are involved.
Dec 11 '07 #3
On 11 Pro, 20:58, Belebele <beluc...@gmail.comwrote:
I am not sure if I understood exactly what you need. If you want to
store value of some templated type, you have to make the whole class
templated

That's not what I want. I want the Interface class to be a class, not
a class template. That way, I could potentially assign to an object of
the Interface class any object that implements the desired interface.
That is:

class B1 {
public:
template <typename T>
void foo(T );

};

class B2 {
public:
template <typename T>
void foo(T );

};

B1 b1;
Interface i(b1);
i.foo(1);

B2 b2;
i = b2;
i.foo(1);

This is simple to implement if the interface does not contain method
templates. I am lost when method templates are involved.
I think it is not possible. You have to store the reference to other
class instance, so the referenced class would have to be derived from
some common class. It is hard to combine template polymorphism and
class polymorphism.
Dec 11 '07 #4
On Dec 11, 2:58 pm, Belebele <beluc...@gmail.comwrote:

I am including your original Interface class here for
reference.
class Interface {
public:
template <typename Wrapped>
Interface(Wrapped& );
// wraps a reference to another object
// that implements the method template

template <typename T>
bool foo(T ); // forwards the call to the wrapped
// object
};
For Interface to be able to keep a reference to the wrapped
object, it needs to store it somewhere. Therefore, it needs
to have a member object of an arbitrary type, namely T.
Conclusion: Interface needs to be a class template.
That's not what I want. I want the Interface class to be a
class, not a class template. That way, I could potentially
assign to an object of the Interface class any object that
implements the desired interface. That is:
One does not prevent the other. Look again at the example you
were given in http://tinyurl.com/2rppm8. It corresponds to the
problem you are explaining.
class B1 {
public:
template <typename T>
void foo(T );

};

class B2 {
public:
template <typename T>
void foo(T );

};

B1 b1;
Interface i(b1);
i.foo(1);

B2 b2;
i = b2;
i.foo(1);

This is simple to implement if the interface does not
contain method templates. I am lost when method templates
are involved.
I don't see how this can be "simple to implement", except by
using function pointers, which is not particularily simple,
safe or fun to play with.

You have two important requirements:

1) Wrapped classes do not derive from a common base class.
Therefore, you need the wrapper class to be templated.

2) Some member functions in the wrapped classes are templated.
Therefore, you need the wrapper class to have as many
templated member functions.

--
Jonathan Mcdougall
Dec 11 '07 #5
I don't see how this can be "simple to implement", except by
using function pointers, which is not particularily simple,
safe or fun to play with.
See Listing 1 on http://www.ddj.com/cpp/184401848 Yep, function
pointers to the rescue. Nothing really too extraordinary.

The method template requirement is what puzzles me.

I would prefer not having to force the Wrapped objects to derive (in
my case artificially) from a base class.
Dec 11 '07 #6
On Dec 11, 5:48 pm, Belebele <beluc...@gmail.comwrote:
I don't see how this can be "simple to implement",
except by using function pointers, which is not
particularily simple, safe or fun to play with.

See Listing 1 on http://www.ddj.com/cpp/184401848. Yep,
function pointers to the rescue. Nothing really too
extraordinary.
I copy the listing (with some corrections) for the sake of the
discussion:

# include <iostream>

struct AbcFuBar
{
virtual ~AbcFuBar()
{
}

virtual void FuBar() = 0;
};

struct BaseFuBar : public AbcFuBar
{
void FuBar()
{
std::cout << "BaseFuBar";
}
};

struct DerivedFuBar : public BaseFuBar
{
void FuBar()
{
std::cout << "DerivedFuBar";
}
};

int main()
{
DerivedFuBar d;
BaseFuBar& b = d;
AbcFuBar& a = b;
a.FuBar(); // output DerivedFuBar
}

This example does not correspond to your original post. It
only demonstrates the use of inheritance and virtual
functions.
The method template requirement is what puzzles me.

I would prefer not having to force the Wrapped objects
to derive (in my case artificially) from a base class.
Basically, you need templates if you don't have a base class.
Otherwise, what will be the type of the member object of your
"Interface" class?

class wrapper
{
public:
template <class T>
wrapper(T& t)
: t_(t)
{
}

private
??? t_;
};

Note that you cannot replace ??? by T, since it only exists in
the constructor. To do this, make wrapper a template:

template <class T>
class wrapper
{
public:
wrapper(T& t)
: t_(t)
{
}

private:
T t_;
};

in which case the constructor does not need to be templated
anymore (unless it should accept things that are not Ts).

Now, if you want to call member functions on the wrapped
oject, you need to know the function names along with the type
and numbers of parameters they take.

template <class T>
class wrapper
{
public:
wrapper(T& t)
: t_(t)
{
}

void f(int i)
{
t_.f(i);
}

private:
T t_;
};

class bar
{
public:
void f(int i)
{
}
};

int main()
{
bar b;
wrapper<barw(b);

w.f(0);
}

To remove the "hardcoded" type information in f(), you can use
templates:

template <class T>
class wrapper
{
public:
wrapper(T& t)
: t_(t)
{
}

template <class P1>
void f(P1 p1)
{
t_.f(p1);
}

private:
T t_;
};

--
Jonathan Mcdougall
Dec 12 '07 #7
On Dec 11, 7:38 pm, Ondra Holub <ondra.ho...@post.czwrote:
On 11 Pro, 20:58, Belebele <beluc...@gmail.comwrote:
I am not sure if I understood exactly what you need. If you want to
store value of some templated type, you have to make the whole class
templated
That's not what I want. I want the Interface class to be a class, not
a class template. That way, I could potentially assign to an object of
the Interface class any object that implements the desired interface.
That is:
class B1 {
public:
template <typename T>
void foo(T );
};
class B2 {
public:
template <typename T>
void foo(T );
};
B1 b1;
Interface i(b1);
i.foo(1);
B2 b2;
i = b2;
i.foo(1);
This is simple to implement if the interface does not contain method
templates. I am lost when method templates are involved.

I think it is not possible. You have to store the reference to other
class instance, so the referenced class would have to be derived from
some common class. It is hard to combine template polymorphism and
class polymorphism.
Do this help you?

#include <string>
#include <iostream>

struct Interface {
template<typename T>
void foo(T& t) {
t.foo("foo()");
}
};

class A {
public:
void foo(const std::string& parameter) {
std::cout << "A::foo( " + parameter + " )" << std::endl;
}
};

class B {
public:
void foo(const std::string& parameter) {
std::cout << "B::foo( " + parameter + " )" << std::endl;
}
};

int main() {
Interface i;
A a;
B b;
i.foo(a);
i.foo(b);
}

But if you need to store the class reference passing it on Interface
class constructor it is not possible unless you declare Interface as a
class template.
Dec 13 '07 #8
On Dec 11, 5:58 pm, Belebele <beluc...@gmail.comwrote:
I am not sure if I understood exactly what you need. If you want to
store value of some templated type, you have to make the whole class
templated

That's not what I want. I want the Interface class to be a class, not
a class template. That way, I could potentially assign to an object of
the Interface class any object that implements the desired interface.
That is:

class B1 {
public:
template <typename T>
void foo(T );

};

class B2 {
public:
template <typename T>
void foo(T );

};

B1 b1;
Interface i(b1);
i.foo(1);

B2 b2;
i = b2;
i.foo(1);

This is simple to implement if the interface does not contain method
templates. I am lost when method templates are involved.
Do this help you?

#include <string>
#include <iostream>

struct Interface {
template<typename T>
void foo(T& t) {
t.foo("foo()");
}

};

class A {
public:
void foo(const std::string& parameter) {
std::cout << "A::foo( " + parameter + " )" <<
std::endl;
}

};

class B {
public:
void foo(const std::string& parameter) {
std::cout << "B::foo( " + parameter + " )" <<
std::endl;
}

};

int main() {
Interface i;
A a;
B b;
i.foo(a);
i.foo(b);

}

But if you need to store the class reference passing it on Interface
class constructor it is not possible unless you declare Interface as a
class template.
Dec 13 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Dave | last post by:
What is the expected output of this program and why??? #include <iostream> using namespace std; class base {
9
by: Karel Miklav | last post by:
In lots of places in a programm I need to identify type of received messages, so I create them as virtual classes and use RTTI to find their type later. But these are simple messages, often without...
3
by: Chris | last post by:
I am having a very strange problem involving virtual functions in template classes. First of all, here is an extremely simplified structure of the two classes I am having problems with. ...
3
by: YellowMaple | last post by:
Is it possible to have pure virtual functions defined in a template class? I'm trying to do something like this: template <typename T> class Singleton { public: static T& getInstance(void) {...
12
by: feel | last post by:
Hi,All I am sure it's an old question. But I just find a interesting design about this: Polymorphism without virtual function in a C++ class. My solution is for some special case, trust me, very...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.