Please look at the following code:
template<class MT>
class ClassA {
public:
int cnt;
};
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
When compiled, g++ gives an error that "cnt" was not declared in the scope.
If I change cnt to this->cnt, it works. However, I am confused. Can someone please explain why would it not work otherwise?
The reason is that cnt is not a dependent name (doesn't depent on the template paremeter), so the rules of the language state that you have to qualify it with this-> or base::.
I figured I'd expand Mark B's answer (though he is totally right).
the rules of the language state that you have to qualify it with this-> or base
The rules of the language are there because there are many situations where the compiler simply cannot know where to look for that name at compile time: cnt could exist in the parent class, or it could not.
Take the following example:
template<class MT>
class ClassA {
public:
};
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
template<>
class ClassA<int>
{
public:
int cnt;
};
How does the compiler know where to find cnt? The parent's members don't exist at declaration time. You can specialize at any time, so this specialization could be in a different file all together, and the specialization in different compilation units could not agree (wacky). The child class could have any sort of parent structure. So the compiler won't even look in the parent (which doesn't exist until instantiation time) until you tell it to.
This leads to the weird (but perfectly logical) behavior below:
template<class MT>
class ClassA {
public:
};
int cnt = 50;
template<class MT>
class ClassB : public ClassA<MT> {
public:
void test() {
cnt++ ;
}
};
template<>
class ClassA<int>
{
public:
int cnt;
ClassA(){cnt=0;}
};
template <>
class ClassB<int> : public ClassA<int>
{
public:
void test() {
cnt++ ;
}
};
int main () {
ClassB<int> bi;
ClassB<float> bf;
bi.test();
bf.test();
std::cout << cnt << std::endl;
std::cout << bi.cnt << std::endl;
}
Which yields
51
1
(so the cnt in the general template does not match the cnt in the specialization).
Compiling a template does NOT automatically look into the base class for names. Here's the only explanation I could find on short notice: http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html
An easy workaround is to add a
using ClassA<MT>::cnt;
somewhere to the definition of your ClassB.
Related
Suppose I have two classes with the same name in the same namespace in two different files.
This is so I can construct another object with each of the two classes, following the same interface but with some functions that behave differently.
For the differently behaving functions, I will redefine them in one instance of the class.
For the functions behaving the same way, I want to construct an instance of the other class and forward calls.
Is there a way to do this? Clearly I can't have two classes in the same namespace, but perhaps I can redefine the namespace/classname of the class I want to be a member in order to forward calls?
For example:
//file_1.h
namespace x {
class y {
}
}
//file_2.h
#include "file_1.h"
namespace x {
class y {
// member of same class in the other file
y memberName;
}
}
You can not modify a class after it has been declared and you can not declare two different classes with the same name.
You can declare a class hierarchy with virtual methods and use a pointer to the base. For example:
class A {
public:
virtual void f() = 0;
};
class B : public A {
void f() override {std::cout << "B" << std::endl;}
};
class C : public A {
void f() override {std::cout << "C" << std::endl;}
};
int main()
{
A *a1 = new B;
A *a2 = new C;
a1->f(); // B
a2->f(); // C
return 0;
}
Although both a1, a2 are pointers to A, the code will print:
B
C
If you do not want to made this class hierarchy public, you can use the pimpl technique. It allows you to hide the real implementation of a class.
For example:
// File: A.h
class A {
class AImpl;
std::unique_ptr<AImpl> m_pimpl;
public:
explicit A();
void f();
};
// File A.cpp
class A::AImpl {
public:
void f() { std::cout << "A" << std::endl;};
};
A::A() : m_pimpl(new AImpl) {
}
void A::f() {
m_pimpl->f();
}
Now, you can define inside your cpp file the implementation of class AImpl. You can even use a class hierarchy for AImpl to create different behaving objects depending on the class that you have created internally.
Suppose I have two classes with the same name in the same namespace in two different files.
Then you have violated a rule called thd ODR or one definition rule. Doing so makes your program ill-formed, no diagnostic required.
If you have a class Alice that wants tomuse another class Bob, but you want two different definitions for how Bob works, the solutions are called "polymorphism".
Polymorphism is the ability for two or more classes to substitute for one.
There are three simple forms of polymorphism. There is using a virtual interface and runtime polymorphism. There is using templates and compile time pokymorphism. Then there is type erasures via function pointers.
The easiest is defining a virtual interface.
struct IBob {
virtual int count() const = 0;
virtual ~IBob() {}
};
struct Alice {
std::unique_ptr<IBob> my_bob = nullptr;
void do_stuff() const {
if(my_bob) std::cout << "Count is:" << my_bob->count() <<"\n";
}
};
now we can define two implementations of IBob:
struct Bob0:IBob{
int count() const final { return 7; }
};
struct Bob1:IBob{
std::unique_ptr<IBob> pBob;
int count() const final {
if(pBob) return pBob->count()*2 +1;
else return 1;
}
};
now Bob1 has a IBob, and it uses that IBob to implement its own count.
The template way looks like:
template<class Bob>
struct Alice {
Bob my_bob;
void do_stuff() const {
std::cout << "Count is:" << my_bob.count() <<"\n";
}
};
and the various Bob implementations need no virtual or inheritance. Here you must pick which Bob at compile time at each point of use.
The manual function pointer type erasure solution is more complex. I'd advise against it.
When you include a file is like adding the content to that cpp file.
So that means you will have the same name for different classes.
There is a possibility to use the same name by using typedef.
class A {
public:
static void func() {}
};
class B {
public:
static void func() {}
};
void funcA() {
typedef A C;
C::func();
}
void funcB() {
typedef B C;
C::func();
}
int main()
{
funcA();
funcB();
return 0;
}
I have two C++ classes such that:
The first class contains a pointer to the second class and has template function that calls second class's public method through a pointer. The function is defined already in the class declaration, for the reason of being a template.
The second class allows the first class to access its private members through friendship mechanism.
Given that, my question is: how do I organize the sources/headers/forward declarations for this situation?
Whatever I tried, it just doesn't compile to an object file.
One sequence is this:
class Class2;
class Class1
{
Class2 * c2;
public:
template<typename T> T DoSomething(T& X)
{
c2->Func();
return X;
};
void FuncFromClass1();
};
class Class2
{
int data;
public:
Class2() : data(0) {};
void Func();
friend void Class1::FuncFromClass1();
};
void Class2::Func()
{
int i;
}
void Class1::FuncFromClass1()
{
int j;
c2 = new Class2;
c2->data = 1;
}
Barks invalid use of incomplete type ‘class Class2’ because it doesn't recognize c2->Func();.
The other one is:
class Class1;
class Class2
{
int data;
public:
Class2() : data(0) {};
void Func();
friend void Class1::FuncFromClass1();
};
class Class1
{
Class2 * c2;
public:
template<typename T> T DoSomething(T& X)
{
c2->Func();
return X;
};
void FuncFromClass1();
};
void Class2::Func()
{
int i;
}
void Class1::FuncFromClass1()
{
int j;
c2 = new Class2;
c2->data = 1;
}
Doesn't recognize friend void Class1::FuncFromClass1();.
The compilation is tried as g++ -c -std=c++11 -Wall test.cpp.
Note I'd rather not make Class1 as entire friend, rather want to keep only one of its methods as a friend to Class2, if at all possible.
Also, I haven't tried the exact same example in Visual Studio in Windows, but saw an entirely isomorphic situation like the one described (within a bigger project) and no complaints came from VS as far as I recall. Is it unique to g++?
Move the implementation of the member function template where definition of Class2 is known.
class Class2;
class Class1
{
private:
Class2 * c2;
public:
// Delcare, don't define
template<typename T> T DoSomething(T& X);
void FuncFromClass1();
};
class Class2
{
private:
int data;
public:
Class2() : data(0) {};
void Func();
friend void Class1::FuncFromClass1();
};
// Define
template<typename T>
T Class1::DoSomething(T& X)
{
c2->Func();
return X;
};
Note that the proposed solution is simple if both classes are defined in one .h file. If the classes are defined in separate .h files, things get a little bit more complex. You'll have to make sure that the .h file where Class1::DoSomething() is defined is #included in every .cpp file where you want to use Class1::DoSomething().
For quite a long time as was thinking about solution to my problem and I finally came to point when I have no other ideas but to ask here.
I have following problem.
Short version. How to inherit static field from base class, but make it unique in each derived class and keep possibility to upcast those classes to parent class?
Long version. I need to create some kind of basic interface for set of classes. Each of this classes need to have one static field and one static method. But I want to be able to pass all those classes as parameters to one universal function which uses those static members. So I was thinking about inheriting them all from one base class.
But of course I can't simply inherit static members and expect them to be unique in each child class. I was trying to use Curiously Recurring Template Pattern (CRTP), but it forces me to make this universal function template too and directly give it class name during each call. That's not good for me.
Also I have problems with making CRTP works when more than one level of inheritance is used (i.e. when I want to derive one more class from class derived from this template base class). Is there any way to achieve what I need?
I know that similar questions were already asked but in most of them authors were glad with CRTP. For me it doesn't seem like solution good enough.
//pseudo-code for what I need, doesn't work of course
class Base {
public:
static int x;
static int GetX() {return x;}
}
class Derived : public Base {};
class NextDerived : public Derived {};
class NextDerived2 : public Derived {};
void Foo(Base& a) {a.x = 10;}
int main {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2); //both Foos modify different static variables
}
//CRTP attempt
template <class C>
class Base {
public:
static int x;
static int GetX() {return x}
};
class Derived : public Base<Derived> {};
int Derived::x = 0;
template <class C>
void Foo(Base<C>& b) {
b.x = 10;
return;
};
int main() {
Derived d;
Foo<Derived>(d);
}
Keep in mind that static variables must also be defined. So for every derived type that you need a separate static variable for, you'll need to define it as well.
Instead, you could use a std::map and a type-id hash to do something similar without the need to clutter your base class. Additionally, this allows you to have any type be used, example:
#include <iostream>
#include <map>
#define out(v) std::cout << v << std::endl
static std::map<std::size_t, int> ExsAndOhs;
template < typename T >
static std::size_t type_id() // in case you don't want RTTI on
{
static char tid;
return reinterpret_cast<std::size_t>(&tid);
}
template < typename T >
void Foo(int _x) { ExsAndOhs[type_id<T>()] = _x; }
template < typename T >
void Foo(T& obj, int _x) { ExsAndOhs[type_id<T>()] = _x; }
template < typename T >
void Print() { out(ExsAndOhs[type_id<T>()]); }
template < typename T >
void Print(T& obj) { out(ExsAndOhs[type_id<T>()]); }
class Base {};
class Derived : public Base {};
class D2 : public Base {};
int main(int argc, char* argv[])
{
// using explicit templates
Foo<Base>(100);
Foo<Derived>(10);
Foo<D2>(42);
Foo<long>(65535);
Foo<int>(1955);
Print<Base>();
Print<Derived>();
Print<D2>();
Print<long>();
Print<int>();
Base b;
Derived d;
D2 d2;
int x = 1;
long y = 1;
// using template deduction
Foo(b, 10);
Foo(d, 42);
Foo(d2, 100);
Print(b);
Print(d);
Print(d2);
Print(x); // still prints 1955
Print(y); // still prints 65535
return 0;
}
This also avoids the need to declare each derived classes static members.
This may not be a good solution for your specific use case, but it is an alternative that achieves what you're asking.
Hope that can help.
Does this CRTP style work for you?
#include <iostream>
using namespace std;
template<class T>
class Base {
public:
static int x;
static int GetX() {return x;}
};
template<class T>
class Derived : public Base <Derived<T> >{};
class NextDerived : public Derived<NextDerived> {};
class NextDerived2 : public Derived<NextDerived2> {};
static int count = 0;
template<class T> int Base<T>::x = 0;
template<class T>
void Foo(Base<Derived<T> >& a) {
a.x = count++;
};
int main() {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2);
cout << d.GetX() << " " << d2.GetX() << endl;
return 0;
}
I'm writing plugins for an application through its C++ SDK. The mechanism is fairly simple. A plugin provides its functionality through predefined interfaces. This is done by having server classes inherit from one implementation class per interface, which contains either pure vitual functions or non-pure functions with default implementations.
This is very practical as SDK clients only have to override those methods that the plugin requires and/or provide an implementation for the (rare) ones with no default.
What has been bugging me is that everything is known at compile time. The virtual function tables and machinery associated with runtime polymorphism are here only for the sake of providing default implementations.
I'm attempting to remove this overhead while keeping the convenience.
As a (very contrived) example, say I have a couple of servers presenting a single interface (named Blah) consisting of only one method with no default implementation.
// SDK header
struct OldImpl_Blah {
virtual ~OldImpl_Blah() =default;
virtual int mult(int) =0;
};
// plugin source
class OldServer3 : public OldImpl_Blah {
public:
int mult(int i) override { return 3 * i; }
};
class OldServer5 : public OldImpl_Blah {
public:
int mult(int i) override { return 5 * i; }
};
For pure virtual functions, straight forward CRTP works just fine.
// SDK header
template <typename T>
struct NewImpl_Blah {
int mult(int i) { return static_cast<T*>(this)->mult(i); }
};
// plugin source
class NewServer3 : public NewImpl_Blah<NewServer3> {
public:
int mult(int i) { return 3 * i; }
};
class NewServer5 : public NewImpl_Blah<NewServer5> {
public:
int mult(int i) { return 5 * i; }
};
The problem is with non-pure virtual functions, i.e. when there is a default implementation for the method.
// SDK header
struct OldImpl_Blah {
virtual ~OldImpl_Blah() =default;
virtual int mult(int i) { return i; } // default
};
// plugin source
class OldServer3 : public OldImpl_Blah {
public:
int mult(int i) override { return 3 * i; }
};
class OldServer5 : public OldImpl_Blah {
public:
int mult(int i) override { return 5 * i; }
};
I tried to combine CRTP with some expression SFINAE trickery and failed.
I guess what I need is some kind of code dispatching where the base class would either provide a default implementation or forward its arguments to the implementation in the derived class, if it exists.
The problem seems to be that the dispatch should rely on information that is not yet available to the compiler in the base class.
A simple solution would be to just remove the virtual and override keywords in the code. But then the compiler wouldn't check that the function signatures match.
Is there some well known pattern for this situation? Is what I'm asking possible at all?
(Please use small words as my expertise with templates is a bit on the light side. Thanks.)
As always, Yet Another Level of Indirection is the solution. In this particular case, it's the well known technique of public non-virtual functions calling private or protected virtual functions. It have its own uses, independent of what is being discussed here, so check it out regardless. Normally it works like this:
struct OldImpl_Blah {
piblic:
virtual ~OldImpl_Blah() = default;
int mult(int i) { return mult_impl(i); }
protected:
virtual int mult_impl(int i) { return i; }
};
// plugin source
class OldServer3 : public OldImpl_Blah {
protected:
int mult_impl(int i) override { return 3 * i; }
};
With CRTP it's exactly the same:
template <class T>
struct OldImpl_Blah {
piblic:
virtual ~OldImpl_Blah() = default;
int mult(int i) { return static_cast<T*>(this)->mult_impl(i); }
protected:
virtual int mult_impl(int i) { return i; }
};
// plugin source
class OldServer3 : public OldImpl_Blah<OldServer3> {
protected:
int mult_impl(int i) override { return 3 * i; }
};
Disclaimer: CRTP is said to eliminate virtual call overhead by nit requiring functions to be virtual. I don't know if CRTP has any performance benefits when functions are kept virtual.
Consider using something like policy design:
struct DefaultMult {
int mult(int i) { return i; }
};
// SDK header
template <typename MultPolicy = DefaultMult>
struct NewImpl_Blah {
int mult(int i) { return multPolicy.mult(i); }
private:
MultPolicy multPolicy;
};
// plugin source
class NewServer3 {
public:
int mult(int i) { return 3 * i; }
};
class NewServer5 {
public:
int mult(int i) { return 5 * i; }
};
void client() {
NewImpl_Blah<NewServer5> myServer;
}
Also note that in theory using final keyword with override enables compilers to dispatch more optimally than vtable approach. I expect modern compilers to optimise if you use final keyword in your first implementation.
Some helpful refs:
mixin design
For more on policy based design you can watch video or read book / article by Andrei Alexandrescu
To be honest I'm not sure I'd use the following code, but I think it does what the OP is asking for.
This is a minimal, working example:
#include<iostream>
#include<utility>
template<class D>
struct B {
template <typename T>
struct hasFoo {
template<typename C>
static std::true_type check(decltype(&C::foo));
template<typename>
static std::false_type check(...);
static const bool value = decltype(check<T>(0))::value;
};
int foo() {
return B::foo<D>(0, this);
}
private:
template<class T>
static auto foo(int, B* p) -> typename std::enable_if<hasFoo<T>::value, int>::type {
std::cout << "D::foo" << std::endl;
return static_cast<T*>(p)->foo();
}
template<class T>
static auto foo(char, B*) -> typename std::enable_if<not hasFoo<T>::value, int>::type {
std::cout << "B::foo" << std::endl;
return 42;
}
};
struct A: B<A> { };
struct C: B<C> {
int foo() {
std::cout << "C::foo" << std::endl;
return 0;
}
};
int main() {
A a;
a.foo();
std::cout << "---" << std::endl;
B<A> *ba = new A;
ba->foo();
std::cout << "---" << std::endl;
C c;
c.foo();
std::cout << "---" << std::endl;
B<C> *bc = new C;
bc->foo();
}
If I did it right, there are no virtual methods, but the right implementation of foo is called, no matter if you are using a base class or a derived one.
Of course, it is designed around the CRTP idiom.
I know, the member detector class is far from being good.
Anyway, it's enough for the purpose of the question, so...
I believe, I understand what you are trying to do. If I am correct in my understanding, that can't be done.
Logically, you would want to have mult in Base to check if mult is present in the child struct - and if it does, call it, if it does not, provide some default implementation. The flaw here is that there always be mult in child class - because it will inherit implementation of checking mult from Base. Unavoidably.
The solution is to name function differently in the child class, and in the base check for presence of differently named function - and call it. This is a simple thing to do, let me know if you'd like the example. But of course, you will loose the beauty of override here.
If my base class has a function func(int) and my derived class has a function func(double), the derived func(double) hides base::func(int). I can use using to bring the base version into the derive's list of overloads:
struct base
{
void func(int);
};
struct derived : base
{
using base::func;
void func(double);
}
OK, great. But what if I'm not sure whether base has a func() or not? ie because I am doing template metaprogramming, I'm not actually sure what base is, but I want to bring its functions up to the same level - if they exist. ie change the above example to:
struct base_with
{
void func(int);
};
struct base_without
{
};
template <typename Base>
struct derived : Base
{
using Base::func; // if Base has a func(), I want to bring it in
void func(double);
}
derived<base_with> testwith; // compiles
derived<base_without> testwithout; // fails :-(
I need using_if like boost::enable_if. Doesn't seem possible...
Thanks in advance.
Since you're willing to put using statements into your derived class, I assume you know beforehands which members you may be interested to bring in. You can do this using boost::enable_if:
struct base_with
{
void func(int) { cout << "func(int)" << endl; }
};
struct base_without { };
// Custom traits, by default assume func() isn't present
template <class T> struct has_func : public boost::false_type { };
template<> struct has_func<base_with> : public boost::true_type { };
// Again, if nothing else is known, assume absence of func(int)
template <typename Base, class UseFunc = void> struct derived : Base
{
derived() { cout << "ctor: derived without" << endl; }
void func(double) { cout << "func(double)" << endl; }
};
// Derived with func(int)
template <typename Base> struct derived<Base, typename boost::enable_if< has_func<Base> >::type> : Base
{
using Base::func;
derived() { cout << "ctor: derived with" << endl; }
void func(double) { cout << "func(double)" << endl; }
};
Sorry for all the printing statements. Now if you try
derived<base_with> testwith;
derived<base_without> testwithout;
testwith.func(10);
testwith.func(10.5);
testwithout.func(10);
testwithout.func(10.5);
you should see
ctor: derived with
ctor: derived without
func(int)
func(double)
func(double)
func(double)
Obviously, this is going to get monstrous if you try to test for several features. If I was doing such mixin-style programming, I'd probably rather use functions with different names for different features so they wouldn't hide each other - then public inheritance would be all that is needed. Interesting question in any case.
I guess I need to do something like
struct dummy_func
{
private:
struct dumb_type {};
// interesting: does this need to be public?
public:
// use a type that no one can see, so func is never chosen by ADT
// and vararg just for paranoia
void func(dumb_type, dumb_type, dumb_type,...) { };
};
...
template <typename T>
struct has_func
{
enum { value = /* insert metaprogramming magic that checks for T::func */ }
};
template <typename Base>
struct derived : Base
{
using enable_if<has_func<Base>, Base, dummy_func>::type::func;
...
};
grrr. Of course this doesn't work because dummy_func is not a base of derived. In my case I could maybe make it derive from it when necessary. But still barely satisfactory.