I have a class called A which looks like this:
class A
{
protected: typedef bool(*fp)();
public:
virtual void back(fp succesor,fp valid,fp solutie,fp show); // this function is defined in the .cpp
};
and a class B derived from A which looks like this:
class B : public A
{
public:
bool succesor(); //defined in cpp
bool valid(); //defined in cpp
bool solutie(); //defined in cpp
bool show(); //defined in cpp
void generate()
{
back(succesor,valid,solutie,nullptr);
}
};
I haven't shown you the constructors and the instantiation of the class, because it's not important in this phase.
The idea is that when I put that back call in the generate function is gives me these 3 errors:
error C3867: 'B::succesor': function call missing argument list; use '&B::succesor' to create a pointer to member
the same but with the other function name
the same but with the other function name
Please, could you suggest me where is my mistake?
Thank you
Related
Playing with C++ 20 modules, I have the following snippet:
export {
template<class T>
class Suite {
private:
std::vector<ConcreteBuilder<T>> things {};
};
template <class T>
class ConcreteBuilder : Builder<T> {
private:
// A collection of things of function pointers or functors
std::vector<std::function<void()>> things;
public:
// Virtual destructor
virtual ~TestBuilder() override {};
// Add a new thing to the collection of things
template<typename Function>
void add(Function&& fn) {
tests.push_back(std::forward<Function>(fn));
}
// override the build() base method from Builder<T>
virtual T build() const override {
return this->things;
}
};
}
And I am getting this Clang error:
error: use of undeclared identifier 'ConcreteBuilder'
std::vector<ConcreteBuilder> things {};
Why I can't access to a type that are in the same module at the same level?
The compiler compiles the file from the top down, not all at once. It is hitting the definition of std::vector<ConcreteBuilder<T>> before it gets to the definition of class ConcreteBuilder.
So, you need to move your definition of Suite after the definition of ConcreteBuilder, so the compiler knows what it is when you use it in the vector definition.
This is the first time I am using class templates so please don't be to harsh if I made a simply mistake.
I have a class template class A<class T>. It has a method init() that is pure virtual and therefore will be implemented separately in every derived class. What all these possible derived classes will have in common is an init(T* i_x) which basically does some general stuff and then calls the init(). Because this will be the same for every derived class I want to define it in the base class template already. But somehow my compiler doesn't find the right function.
If I try to use the init(T* i_x) on an object of a derived class A_der I get the error:
no matching function for call to 'A_der::init(B_der*)
The classes used for the template parameter T will all be derived from another class B. Therefore the error message involves the class B_der which is derived from class B.
I boiled the problem down to a small example, which should involve everything that is important for the problem. If I try to compile this example in Visual Studio (normally I work in STM32CubeIDE) I get the following error
Severity Code Description Project File Line Suppression State
Error C2660 'A_der::init': function does not take 1
arguments template_class-overload_inherited_method [...]\main.cpp 8
So somehow the only function the compiler finds at this point is init() but not the base class template method init(T* ).
Can somebody please tell me why it is like that and what can I do to get the behaviour I want (without implementing a similar init(T* ) in every derived class of A?
Here is my example code:
base class template A - declaration - A.hpp
template<class T>
class A
{
protected:
T* m_x;
public:
virtual void connect(T* i_x) final;
virtual void init() = 0;
virtual void init(T* i_x) final;
};
base class template A - implementation - A.cpp
#include "A.hpp"
template<class T>
void A<T>::connect(T* i_x)
{
//some checks
m_x = i_x; //connects object of B to A
}
template<class T>
void A<T>::init(T* i_x)
{
connect(i_x);
init();
}
derived class A_der
#include "A.hpp"
#include "B_der.hpp"
#pragma once
class A_der : public A<B_der>
{
void init() override;
};
void A_der::init()
{
//Initialization which needs a B_der connected already
}
main.cpp
#include "B_der.hpp"
#include "A_der.hpp"
int main(void)
{
B_der testB;
A_der testA;
testA.init(&testB);
return 0;
}
For the sake of completeness:
class B
{
};
class B_der : public B
{
};
EDIT - Solved
Thanks a lot for the fast replies.
The combination of the comments from #BoP and #Jarod42 solved the problem.
I had to unhide the method with using A<B_der>::init (actually renaming might be the more elegant way) and move the implementation of A into A.hpp.
I will offer the updated example which builds successfully with Visual Studio 2019 for me here:
base class A
template<class T>
class A
{
protected:
T* m_x;
public:
virtual void connect(T* i_x) final;
virtual void init() = 0;
virtual void init(T* i_x) final;
};
template<class T>
void A<T>::connect(T* i_x)
{
//some checks
m_x = i_x; //connects object of B to A
}
template<class T>
void A<T>::init(T* i_x)
{
connect(i_x);
init();
}
derivad class A_der
A_der.hpp
#include "A.hpp"
#include "B_der.hpp"
class A_der : public A<B_der>
{
public:
void init() override;
using A<B_der>::init;
};
A_der.cpp
#include "A_der.hpp"
void A_der::init()
{
//Initialization which needs a B_der connected already
}
main.cpp
#include "B_der.hpp"
#include "A_der.hpp"
int main(void)
{
B_der testB;
A_der testA;
testA.init(&testB);
return 0;
}
for completeness
B.hpp
class B
{
};
B_der.hpp
#include "B.hpp"
class B_der : public B
{
};
I also forgot to make the methods of A_der public in the earlier example, this is corrected here. And I removed the #pragma onces in this example.
class A_der : public A<B_der>
{
void init() override;
};
When you declare a function init in the derived class, it hides all things named init from the base class. This is just like when declaring something in an inner scope - it hides things with the same name from outer scopes.
There are ways to import the hidden names, but an easy solution would be to just chose a different name, like init_base. Or, probably better, pass a parameter to the class constructor.
I'm currently working on a project that has several classes, and at times, I have to call functions from other classes to make things work. I want to know if the way I'm doing it is efficient, or if there is another way I should be doing this. Here's an example
class FirstClass{ // FirstClass.cpp
public:
void aFunction(){
std::cout << "Hello!";
}
private:
}
Let's say I wanted to call aFunction in another class, I'd do this:
#include "FirstClass.cpp"
class SecondClass{ //SecondClass.cpp
public:
FirstClass getFirstClass;
// I would then use getFirstClass.aFunction();
// whenever I want to call.
private:
}
I don't feel like this is very productive. Is there a better way of doing this?
First of all why including source file FirstClass.cpp?
The proper way is to create a header file FirstClass.h and a source file FirstClass.cpp and include the header inside the source and in main.cpp.
Second: A member function is a member function it is a member of an object so you need an instance of that class to call its member. If you don't want to instantiate the class then declare the member function as a static function then you can either call it using an object or directly using class name followed by scope operator: FirstClass::aFunction().
// FirstClass.h
class FirstClass{ // FirstClass.cpp
public:
void aFunction();
}
// FirstClass.cpp
#include "FirstClass.h"
void FirstClass::aFunction(){
std::cout << "Hello!";
}
// SecondClass.h
#include "FirstClass.h"
class SecondClass{
public:
void foo();
private:
FirstClass getFirstClass;
};
// SecondClass.cpp
void SecondClass::foo()
{
getFirstClass.aFunction();
}
To make it a static:
struct A
{
static void do_it(){std::cout << "A::do_it()\n";}
};
struct B
{
void call_it(){ A::do_it();}
};
There's nothing with "productivity" to whether have a static or non-static data/function member.
The semi-colon is not redundant at the end of class body so you need t add them: class FirstClass{ }; class SecondClass{};.
I want to create a class with a callback function, it should be possible to use either an external function as callback, or the class will assign a member function as callback by default. See my code sample here:
#include <functional>
class Foo
{
public:
typedef std::function<void(void)> CallbackType;
Foo(CallbackType callback = defaultCallback): _callback(callback) {}
// code sample works only if this function is defined static:
static void defaultCallback(void) {}
CallbackType _callback;
};
void externCallback(void) {}
int main()
{
Foo fooExtern(externCallback);
}
As mentioned in the code, the sample works only if 'defaultCallback' is defined static. When not using the static keyword, I get the error:
cannot convert ‘Foo::defaultCallback’ from type ‘void (Foo::)()’ to type ‘Foo::CallbackType {aka std::function}’
However, I want also to be able to use this class as a parent class, and I want to define the 'defaultCallback' as virtual (which is not possible at the same time when defining it as static). Has anyone a suggestion how I can make the code work without using a static member function as default constructor argument?
class Foo
{
public:
using CallbackType = std::function<void(void)>;
Foo() : Foo([this]{defaultCallback();}) {}
explicit Foo(CallbackType callback) : _callback(callback) {}
void defaultCallback(void) {}
CallbackType _callback;
};
I have two simple classes, very simple One is like master table and contains list of pointers to class Two, and class Two contains one pointer to class One. In every class there is function which call methods over pointers, but I am getting error like
error C2027: use of undefined type
---- class One.h"
#include "Two.h"
class One {
public:
list<Two*> something;
void t(){pointer on Two call methods}
};
and
---------class Two.h
class One;
class Two {
public:
One* something;
void t(){pointer on One call methods}
};
How to solve this problem ?
Move your method defenition to .cpp and include the required header with the type defenition.
Two.h
class One;
class Two {
public:
One* something;
void t();
};
Two.cpp:
void Two::t() {...}
This is required because compiler is not able to generate the code for calling a method of an undefined type