This question already has answers here:
automatically convert list of pointers to derived class to list of pointers to base class
(4 answers)
Closed 4 years ago.
I would like to know why the compiler doesn't allow the second use of "print_all" function.
I have to give an example of a bad thing that could happen if the compiler would allow it.
#include <iostream>
#include <list>
using std::list;
class foo {
class bar : public foo {
static void print_all(list<foo *> &L) {
list<foo *> LF;
list<bar *> LB;
print_all(LF); // works fine
print_all(LB); // static semantic error
}
};
};
list<foo *> is an unrelated type to list<bar *>. The function is specified to accept one, but not the other.
But class bar inherits from class foo
That is irrelevant, because the argument of your function isn't foo&. What's relevant is whether list<bar *> inherits list<foo *>. It doesn't. std::list does not have a base class.
Related
This question already has an answer here:
C++ Forward Declaration confusion
(1 answer)
Closed 5 years ago.
I'm trying to implement polymorphism, as can be seen by the code below. I want vector of expressions of type class expression. these expressions will have a right and left parameter object of type Parameter class. As it may have been guessed, this could recurse until one hits a string "a_string" or "an_id." However, the compiler doesn't, first of all, know what type "Expression" is for the vector. Any help is needed. Thank you.
#ifndef PARAMETER_H
#define PARAMETER_H
#include <string>
#include <vector>
using namespace std;
class Parameter
{
private:
string a_string;
string an_id;
vector<Expression> expressions;
public:
Parameter(bool expr_stringID);
};
class Expression : public Parameter
{
private:
Parameter left_parameter;
Parameter right_parameter;
char op;
public:
};
#endif
Poymorphism either requires virtual functions (at least a virtual destructor), or the CRTP to realize Static Polymorphism.
You provide neither of these with your example.
This question already has answers here:
Using generic std::function objects with member functions in one class
(6 answers)
Closed 7 years ago.
I know, that this question was already asked here, but I believe that my particular example is unique:
#include <functional>
#include <map>
#include <vector>
class Bar{
public:
static unsigned myFunc(const std::vector<std::string> &input){return 1;};
};
class Foo{
friend class Bar;
public:
using CommandFunction = std::function<unsigned(const std::vector<std::string> &)>;
std::map<std::string, CommandFunction> Commands;
};
int main(){
Foo oFoo;
Bar oBar;
oFoo.Commands["myFunc"] = oBar.myFunc;
return 0;
}
I want to make the myFunc function non-static, so it will be able to access private members of the Bar class. But I have no clue how to implement this idea. Simply removing the static keyword obviously will raise an error during compilation (invalid use of non-static function). Is there any 'clean' way of solving this problem? And by 'clean' I mean not using global variables and objects.
Update
I think I need to clarify the purpose of the design I described above.
I'm using a wrapper to the GNU readline library. It is represented by the Foo class. Basically it holds a set of function pointers inside the Commands map and executes them based on the user input.
The Bar class is a set of functions which share common resources (private members of the Bar class).
Lambda could be a solution for you:
class Bar{
public:
std::function<unsigned(const std::vector<std::string>&)> myFunc{ [](const std::vector<std::string>& x){return 1;}};
};
This question already has answers here:
Can I avoid an ambiguity, when I declare a fixed length vector in class?
(2 answers)
Closed 8 years ago.
Can someone explain me why I can make a vector in the int main(), like this:
std:: vector<double> a(20);
but I cannot use this while i am creating a c++ class:
class A
{
std:: vector<double> a(20);
}
You need to initialize the vector in A's constructor:
#include <vector>
class A
{
std::vector<double> a;
public:
A() : a(20) {}
};
You need a constructor that initializes the vector in order to get the behavior you want. (Also I see some syntax mistakes that need to be corrected in the question.) The class will end up looking something like this:
#include<vector>
class A{
public://make the constructor public
A():a(20)//initialize the vector in the constructors initialization list
{}
std::vector<double> a; //can be public or private depending on your use case
}; //don't forget the trailing semicolon!!!
This question already has answers here:
C++ inheritance, base methods hidden
(2 answers)
Closed 8 years ago.
In the following code:
struct X{
void stream(int){}
};
struct Y : public X{
void stream(int, int){}
};
int main()
{
Y y;
y.stream(2);
}
Why X::stream(int) is not inherited?
Or it is hided with Y::stream(int, int). If so, why it hidden, not overridden?
Names in derived classes do indeed hide identical names in base classes. This is deliberate. If the base class changes, you don't suddenly and silently want to see a different overload set in your derived class.
To unhide base names explicitly, add using X::stream; into your derived class.
This question already has answers here:
Restrict C++ Template Parameter to Subclass
(8 answers)
Closed 7 years ago.
Is there any way to make a template only work with child classes of a base class? Something like this:
template<BaseClass T>
class FooBar
{
// ...
};
Either use a static assert from your favourite C++ library (such as this boost example), or put a call in the constructor (or other code which will always be generated when the code is used) to a do-nothing function taking a BaseClass type, for example:
template<class T>
class FooBar
{
public:
FooBar () {
Check(static_cast<T*>(0));
}
private:
void Check ( BaseClasse* ) {}
};
(not tested)
Not directly, but you can test it in the constructor using Boost:
#include <boost/type_traits/is_base_of.hpp>
#include <boost/static_assert.hpp>
template<class T>
class FooBar{
FooBar(){
BOOST_STATIC_ASSERT(boost::is_base_of<BaseClass,T>::value);
}
};
Or if you don't want a static assert, something like this is also nice sometimes:
typedef char ERROR_T_must_be_derived_from_BaseClass[boost::is_base_of<BaseClass,T>::value ? 1 : -1];
Since whoever compiles your code will be brought to this line and has a "readable" error message.
There are ways to make it work with a static assert. See Boost.StaticAssert