473,794 Members | 2,804 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(Wrapp ed& );
// 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 1973
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(Wrapp ed& );
// 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<typena me Wrapped>
class Interface {
public:
Interface(Wrapp ed& 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(Wrapp ed& );
// 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 << "DerivedFuB ar";
}
};

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...@po st.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<typena me 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<typena me 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
1493
by: Dave | last post by:
What is the expected output of this program and why??? #include <iostream> using namespace std; class base {
9
2131
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 content, and I hate how I make their base class: by adding a dummy virtual function. Is there another way? -- Regards,
3
3940
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. template<class Type> class base { public: base& operator/=(const base&); Type *image;
3
3329
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) { if(m_pInstance == NULL)
12
2543
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 special. 1 single root class tree 2 the leaf(lowest level) classes are sealed which means we should not inherite class from them. 3 PImpl idiom. There is only one data mumber in root class and there is no any other data mumber in child class and...
0
9672
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9519
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10435
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10000
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9037
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7538
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6779
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5436
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5563
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.