What's the best way to do this...? (templates/inheritance problem)

F

fungus

I've got a big template class "A" and I want to write another template
"B" which is exactly the same as A except for one method (let's call
it "foo()").

Is there a way to do this without complete copy/paste of "A"? I'd like
to do it with only one copy of the common code.

nb. foo() can't be static, it needs access to class members....

template <class T> class A {
void foo();
};

template <class T> class B {
void foo(); // I want a different "foo()" here...
};



On a related note, something which came up while I was messing around
with this is that when I inherit from a class ("A"), all the
constructors in "A" are hidden.

class A {
public:
A(int);
};

class B : public A {
public:
// Compiler writes a constructor for me, hiding A(int)...
};

main() {
// Doesn't work...compiler says 'int' can't be converted to 'const
B&'
B b(42);
}

How can I make A's constructors visible? I read the faq and tried
adding
a "using A::A", but it makes no difference...

class B : public A {
public:
using A::A; // Makes no difference...
};


faq: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
 
V

Victor Bazarov

fungus said:
I've got a big template class "A" and I want to write another template
"B" which is exactly the same as A except for one method (let's call
it "foo()").

Is there a way to do this without complete copy/paste of "A"? I'd like
to do it with only one copy of the common code.

Is that a trick question? The first rule of the class hierarchy:
if two classes are very similar except for some minor differences,
extract the common portion into a separate class and make your two
classes inherit that.

It goes the same for class templates. The common functionality has
to be extracted into another template. Both class templates inherit
from that [base] template.
nb. foo() can't be static, it needs access to class members....

template <class T> class A {
void foo();
};

template <class T> class B {
void foo(); // I want a different "foo()" here...
};



On a related note, something which came up while I was messing around
with this is that when I inherit from a class ("A"), all the
constructors in "A" are hidden.

Not hidden. The constructors are special function that are never
_inherited_ .
class A {
public:
A(int);
};

class B : public A {
public:
// Compiler writes a constructor for me, hiding A(int)...
};

main() {
// Doesn't work...compiler says 'int' can't be converted to 'const
B&'
B b(42);
}

How can I make A's constructors visible?

You cannot. You can only create a constructor in 'B' that will
take one argument and simply forward it to the base class' c-tor.
See "initialisation of base classes" in your favourite C++ book.
I read the faq and tried
adding
a "using A::A", but it makes no difference...

class B : public A {
public:
using A::A; // Makes no difference...
};


faq:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9

V
 
F

fungus

Is that a trick question?

Not really, see below...
Not hidden. The constructors are special function that are never
_inherited_ .

Aha! So the correct answer to the first question is
really "no, you can't just change a single function".

To make it work I have to change the function *and*
rewrite all the constructors in my derived classes.
 
K

Kai-Uwe Bux

fungus said:
Not really, see below...


Aha! So the correct answer to the first question is
really "no, you can't just change a single function".

To make it work I have to change the function *and*
rewrite all the constructors in my derived classes.

You can use templated constructors:

class B : public A {

B () : A () {}

template < typename X >
B ( X x ) : A ( x ) {}

template < typename X, typename Y >
B ( X x, Y y ) : A ( x, y ) {}

...

B ( B const & other ) : A ( other ) {}


};

If all constructors of A take at most 2 arguments, the above would suffice.


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top