I am having trouble converting a pointer to a templated derived class to a base class pointer for the purposes of storing in a map(and obviously retrieving it later.). I have:
#include <map>
//Role.h
class RoleBase{};
enum class RoleEnum : int;
template<RoleEnum role>
class Role : public RoleBase{};
//Relationship.h
class Relationship{
public:
template<RoleEnum role>
Role<role>* getRole(){
auto it=RoleMap.find(role);
if ( it == RoleMap.end() ) {
return nullptr;
} else {
RoleBase* roleBase= it->second;
return static_cast<Role<role>* >(roleBase);
}
}
std::map<RoleEnum,RoleBase*> RoleMap;
};
//squash.h
enum class RoleEnum : int
{
Player,
Referee
};
template<> class Role<RoleEnum::Player>{};
template<> class Role<RoleEnum::Referee>{};
class SquashGame: public Relationship{
public:
SquashGame(){
RoleBase* playerRole=new Role<RoleEnum::Player>; //problematic
RoleMap.emplace(RoleEnum::Player,playerRole);
}
};
int main() {
SquashGame squashGame;
squashGame.getRole<RoleEnum::Player>();
return 0;
}
Why is that and is there a way of fixing that so I can template a class with enum values for the purposes of calling externally by a getClass<Enum> function, as is hopefully clear in the example?
The problem is simple: your redefinition of Role
template<> class Role<RoleEnum::Player> {}
Doesn't extend RoleBase.
Either remove it or change it to:
template<> class Role<RoleEnum::Player> : public RoleBase {}
Related
If one wants to implement Clone pattern in C++, he might not be sure about safety, because derived class may forget to override it:
struct A {
virtual A* Clone() const {
return new A(*this);
}
}
struct B : A {
int value;
};
int main() {
B b;
// oops
auto b_clone = b.Clone();
delete b_clone;
}
What are the possible ways to improve Clone pattern in C++ in this regard?
A more general question has been asked:
Forcing a derived class to overload a virtual method in a non-abstract base class
However, it seems to be too general to have a good solution in C++ -- the discussion is about possible ways to enforce method override. I'm more interested in discovering a useful pattern, which might help in the exact case of using Cloneable pattern.
This is an elaboration of one of the answers, suggesting runtime check using typeid:
Forcing a derived class to overload a virtual method in a non-abstract base class
Using CRTP, one can come up with the following basic idea:
Create class Cloneable<Derived>, which manages cloning for Derived, and adds all the needed runtime checks (seems like that compile-time checks are not possible even with CRTP).
However, it is not trivial, and one also has to manage inheritance through Cloneable, as described:
#include <memory>
#include <cassert>
#include <type_traits>
#include <typeinfo>
class CloneableInterface {
public:
virtual std::unique_ptr<CloneableInterface> Clone() const = 0;
};
template <class... inherit_from>
struct InheritFrom : public inherit_from... {
};
template <class Derived, class AnotherBase = void, bool base_is_cloneable = std::is_base_of_v<CloneableInterface, AnotherBase>>
class Cloneable;
// three identical implementations, only the inheritance is different
// "no base is defined" case
template <class Derived>
class Cloneable<Derived, void, false> : public CloneableInterface {
public:
std::unique_ptr<CloneableInterface> Clone() const override {
assert(typeid(*this) == typeid(Derived));
return std::make_unique<Derived>(static_cast<const Derived&>(*this));
}
};
// Base is defined, and already provides CloneableInterface
template <class Derived, class AnotherBase>
class Cloneable<Derived, AnotherBase, true> : public AnotherBase {
...
};
// Base is defined, but has no CloneableInterface
template <class Derived, class AnotherBase>
class Cloneable<Derived, AnotherBase, false> : public AnotherBase, public CloneableInterface {
...
};
Usage example:
class Base : public Cloneable<Base> {
};
// Just some struct to test multiple inheritance
struct Other {
};
struct Derived : Cloneable<Derived, InheritFrom<Base, Other>> {
};
struct OtherBase {
};
struct OtherDerived : Cloneable<OtherDerived, InheritFrom<OtherBase>> {
};
int main() {
// compiles and runs
auto base_ptr = std::make_unique<Base>();
auto derived_ptr = std::make_unique<Derived>();
auto base_clone = base_ptr->Clone();
auto derived_clone = derived_ptr->Clone();
auto otherderived_ptr = std::make_unique<OtherDerived>();
auto otherderived_clone = otherderived_ptr->Clone();
}
Any critics and improvement suggestions are welcome!
C++17 and newer offers an std::any. You could in theory, then, make a clone function that returns an std::any* instead:
struct A {
virtual std::any* Clone() const {
return new A(*this);
}
}
struct B : A {
int value;
// I suppose it doesn't have to be virtual here,
// but just in case we want to inherit the cloning capability from B as well
virtual std::any* Clone() const { // Note: you still need to override this function
return new B(*this); // in the lower levels, though
}
};
// Note: I'm still on MSVS2010, so this C++17 code is untested.
// Particularly problematic could be this main
int main() {
B b;
// Here is the clone
auto b_clone = std::any_cast<B*>(b.Clone());
delete b_clone;
}
Again, this is untested, but it should work in theory.
I am trying to implement builder pattern with fluent interface for building the objects in C++. I want the builder to follow CRTP pattern.
In Java, I would do something similar to the below code. How do I do the same in C++?
The below is some java code that has a base class and a derived class. The derived class's builder inherits the base class's builder..
// Base class
public abstract class BaseClass {
private final int base_class_variable;
BaseClass(final Builder <?> builder) {
this.base_class_variable = builder.base_class_variable;
}
public abstract static class Builder <B extends Builder> {
int base_class_variable;
public B setBaseClassVariable(final int variable) {
this.base_class_variable = variable;
return self();
}
protected abstract B self();
}
}
// Derived class
public final class DerivedClass extends BaseClass {
private final int derived_class_variable;
private DerivedClass(final Builder builder) {
super(builder);
this.derived_class_variable = derived_class_variable;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder extends BaseClass.Builder <Builder> {
private int derived_class_variable;
public Builder setDerivedClassVariable(final int variable) {
this.derived_class_variable = variable;
return self();
}
public DerivedClass build() {
return new DerivedClass(this);
}
#Override
protected Builder self() {
return this;
}
}
}
// Creating an instance of DerivedClass
DerivedClass dInstance = DerivedClass.builder()
.setBaseClassVariable(5)
.setDerivedClassVariable(10)
.build();
Here is one way to do it in C++:
template <typename T>
class Builder {
public:
static T builder() { return {}; }
T & build() {return static_cast<T&>(*this); }
};
template <typename T>
class BaseClass : public Builder<T> {
int base_class_variable;
public:
T& setBaseClassVariable(int variable) {
base_class_variable = variable;
return static_cast<T&>(*this);
}
};
class DerivedClass : public BaseClass<DerivedClass> {
int derived_class_variable;
public:
DerivedClass& setDerivedClassVariable(int variable) {
derived_class_variable = variable;
return *this;
}
};
int main()
{
// Creating an instance of DerivedClass
DerivedClass dInstance = DerivedClass::builder()
.setBaseClassVariable(5)
.setDerivedClassVariable(10)
.build();
}
Here is an example that will only allow the values to be changed on an rvalue reference (as returned by the builder):
#include <utility>
template <typename T>
class Builder {
public:
static T builder() { return {}; }
T & build() {return static_cast<T&>(*this); }
};
template <typename T>
class BaseClass : public Builder<T> {
int base_class_variable;
public:
T&& setBaseClassVariable(int variable) && {
base_class_variable = variable;
return std::move(static_cast<T&>(*this));
}
};
class DerivedClass : public BaseClass<DerivedClass> {
int derived_class_variable;
public:
DerivedClass&& setDerivedClassVariable(int variable) && {
derived_class_variable = variable;
return std::move(*this);
}
};
int main()
{
// Creating an instance of DerivedClass
DerivedClass dInstance = DerivedClass::builder()
.setBaseClassVariable(5)
.setDerivedClassVariable(10)
.build();
//dInstance.setBaseClassVariable(34); // will not compile
}
Here is a third solution that uses a Proto class which is returned by the builder(). The private member functions have to be specified with using statements to that they can be made available for public use by Proto. Finally the build() function returns the DerivedClass which does not expose the member functions.
template<typename T>
class BaseClass;
class DerivedClass;
template <typename T>
class Proto : public T {
public:
using BaseClass<T>::setBaseClassVariable;
using T::setDerivedClassVariable;
};
template <typename T>
class Builder {
public:
static Proto<T> builder() { return {}; }
T& build() { return static_cast<T&>(*this); }
};
template <typename T>
class BaseClass : public Builder<T> {
int base_class_variable;
Proto<T>& setBaseClassVariable(int variable) {
base_class_variable = variable;
return static_cast<Proto<T>&>(*this);
}
friend class Proto<T>;
};
class DerivedClass : public BaseClass<DerivedClass> {
int derived_class_variable;
Proto<DerivedClass>& setDerivedClassVariable(int variable) {
derived_class_variable = variable;
return static_cast<Proto<DerivedClass>&>(*this);
}
friend class Proto<DerivedClass>;
};
int main()
{
// Creating an instance of DerivedClass
DerivedClass dInstance = DerivedClass::builder()
.setBaseClassVariable(5)
.setDerivedClassVariable(10)
.build();
//dInstance.setBaseClassVariable(34); // cannot access private member
}
This approach might inspire something better, so I think it should be shared.
First create a class for the members you want to supply using the builder pattern, lets call it the members class and the immutable class to construct the builder class.
The members class will used for:
The builder class will inherit from it.
The builder class accepts it in its constructor, for supplying all the const values for the const members.
Now we want to create an fluent interface for setting the member variables on the members class.
A conflict appears: To make the builder class members const the members class also needs to have them const.
But fluent construction requires a way of giving the arguments one at a time and ideally a way to control what order it is possible to give the arguments in.
Example:
We have a class representing a running process, to construct it we need to know:
1.(Command) What command to execute
2.(Mode) Will only reading from the stdout be required(read mode) or will it be used interactively requiering the ability to write to its stdin(write mode).
3.(Target) Where shall the stdout be redirected to? cout, a file or a pipe?
For simplicity all the arguments will be represented by strings.
Limiting the valid methods after each provided argument is great for autocompletion, but it requires us to define a scope with the valid methods
and what scope it will transition to- for each stage in the construction.
Perhaps a type dependent namespace would be better, but I wanted to reuse the members class if possible.
Each argument interface is represented by a class with method(s) for supplying a constructor argument.
The method will return an object having the next interface as its type for supplying the next constructor argument or the finished builder object.
I reuse the same object for all construction stages but the interface changes by static casting.
We start by creating the last interface the client will use before the builder class will be constructed, in this case (3) the target argument.
Lets name if after that:
struct Target : protected members_class
{
builder_class havingTarget( const string& _target )
{
this->target = target;
return builder_class ( *(this) ) ;
}
};
The builder class is constructable by giving it an members_class object, we inherit from the members_class, so we can return a constructed builder class by supplying the this pointer.
Before the target interface we have the interface for setting the mode argument:
struct Mode : protected Target
{
Target& inMode( const string& mode )
{
this->mode = mode;
return static_cast<Target&>(*this);
}
};
Mode inherits from target, for switching to the target interface after supplying the mode argument, we cast the this pointer to the target interface.
Last the Command interface:
struct Command : protected Mode
{
Mode& withCommand( const string& command )
{
this->command = command;
return static_cast<Mode&>(*this);
}
};
Inheriting from mode and returning a this pointer casted to the mode type after taking the command argument.
But we have a conflict, the members class is used by the builder class for inhereting the members and we want them to be const.
But the builder pattern uses the member class in a way where each argument is provided one at a time.
struct members_class
{
string target;
string mode;
string command;
};
First lets enable a way to supply a template argument that will decide if the members will be const or not:
template <typename T>
using noop = T;
template< template <typename> class constner = noop >
struct members_dyn_const
By default the argument is a no operation, but if std::remove_const_t is supplied the members will not be const as they are declared like this:
constner<const string> target;
constner<const string> mode;
constner<const string> command;
two aliases for the two ways of creating the class:
using members = members_dyn_const<>;
using members_mutable = members_dyn_const<std::remove_const_t>;
Now we want to enable construction of a const members class with a mutable member class:
template< template <typename> class C>
members_dyn_const( members_dyn_const<C> m) : target(m.target), mode(m.mode), command(m.command){}
But we also needs to define default values for the members when it is constructed as a mutable class:
members_dyn_const () : target(""), mode(""), command(""){}
Now we define the builder class inhereting from the const members class, but accepting an mutable members class for construction of the const:
class base_process : protected members
{
public:
base_process( members_mutable _members ) : members( _members ) {}
Now we can construct a builder class with:
process_builder.withCommand( "ls" ).inMode( "read" ).havingTarget( "cout" );
and an immutable class is created with const members.
I havent seen this approach described anywhere else, so I wanted to share it as it might provide inspiration for a better way, but I cant really recommend it and I havent really tested or polished the code beyond a proof of concept.
#include <string>
#include <iostream>
using namespace std;
namespace process
{
namespace details
{
template <typename T>
using noop = T;
template< template <typename> class constner = noop >
struct members_dyn_const
{
friend class members_dyn_const< noop >;
template< template <typename> class C>
members_dyn_const( members_dyn_const<C> m) : target(m.target), mode(m.mode), command(m.command){}
members_dyn_const () : target(""), mode(""), command(""){}
protected:
constner<const string> target;
constner<const string> mode;
constner<const string> command;
};
using members = members_dyn_const<>;
using members_mutable = members_dyn_const<std::remove_const_t>;
namespace builder
{
class base_process : protected members
{
public:
base_process( members_mutable _members ) : members( _members ) {}
void test() { /*command = "X";*/ cout << "Executing command: " << command << " in mode " << mode << " having target " << target << endl; }
};
namespace arguments
{
struct Target : protected members_mutable
{
base_process havingTarget( const string& _target )
{
this->target = target;
return base_process( *(this) ) ;
}
};
struct Mode : protected Target
{
auto& inMode( const string& mode )
{
this->mode = mode;
return static_cast<Target&>(*this);
}
};
struct Command : protected Mode
{
Mode& withCommand( const string& command )
{
this->command = command;
return static_cast<Mode&>(*this);
}
};
}
}
}
using details::builder::base_process;
using details::builder::arguments::Command;
Command process_builder = Command();
}
using namespace process;
int main()
try
{
process_builder.withCommand( "ls" ).inMode( "read" ).havingTarget( "cout" ).test();
return 0;
}
catch( exception& e )
{
cout << "ERROR:" << e.what() << endl;
return -1;
}
https://onlinegdb.com/BySX9luim
I'd need to create a type erasure pattern which would allow to retrieve all the contained objects inheriting from a given base class. As far as I know, a popular type erasure like boost::any allows to retrieve an object with any_cast only if the requested and contained classes matches exactly, so it won't fit my needs.
I could solve the problem with template class which mimicks the inheritance relationship of the template argument. For example, TemplateClass<Derived> should be a child of TemplateClass<Base>, so that the following example would work:
// Suppose all clases have virtual destructors so that vtable and RTTI info are available
class ObjectWrapperBase {
}
template<class DataType>
class ObjectWrapperT: public ObjectWrapperBase {
public:
ObjectWrapperBase(T* ptr): dataObjPtr(ptr){}
DataType *dataObjPtr;
}
class Base{}
class Derived: public Base{}
class NotDerivedFromBase{}
int main(){
std::vector<ObjectWrapperBase*> v;
v.push_back(new ObjectWrapperT<Base>(new Base));
v.push_back(new ObjectWrapperT<Derived>(new Derived));
v.push_back(new ObjectWrapperT<NotDerivedFromBase>(new NotDerivedFromBase));
// Now suppose I want to retrieve all the Base and children objects in v
// If ObjectWrapperT<Derived> is a child of ObjectWrapperT<Base> I can write:
for(int i = 0; i < v.size(); i++){
ObjectWrapperT<Base> *wPtr = dynamic_cast<ObjectWrapperT<Base>*>(v[i]);
if(wPtr){
Base *basePtr = wPtr->dataObjPtr;
}
}
}
Is there a pattern to achieve this behavior? Or eventually another solution?
Thanks.
You cannot do exactly what you want, but you can get something closer with templates and operators.
As a minimal, working example:
#include<type_traits>
template<typename D>
struct S {
S(D *d): d{d} {}
template<typename B, typename = std::enable_if_t<std::is_base_of<B, D>::value>>
operator S<B>() {
return {d};
}
private:
D *d;
};
struct B {};
struct D: B {};
struct A {};
int main() {
S<D> sd{new D};
S<B> sb = sd;
// S<A> sa = sd;
}
If you toggle the comment to the last line, it won't compile anymore for A is not a base of B.
I don't know if it is what you're looking for but you can do something like this:
template <typename T>
class Derived : public T
{
};
And then instantiate it with a mother class named Base like this:
Derived<Base> object;
You will finally get this from Base:
class Derived : public Base
{
};
I'm trying to let the return type of doSomeMethod() be the same as the operator() in the base class but if it's declared as protected the compiler rejects the code with error: no type named 'type' in 'std::result_of'. It works if it's public but i wonder if I could get it working for the protected case too since.
Here is simple code reproducing the error.
#include <type_traits>
class base
{
protected:
int operator()(){return 1;};
};
class child : private base
{
auto static doSomeMethod()
-> typename std::result_of<base()>::type
{
return 1;
}
};
EDIT:
Ok thanks Kerrek SB and Dietmar Kühlr for your solutions and explanations. After playing around with it I found this solution that is more readable and works (at least in my real case where child is template class and base one of its template parameters) more reliable.
But it seems that it goes a bit against your explanations. Or is it just the way std::result_of<> is broken in this case?
#include <type_traits>
class base
{
protected:
double operator()(){ return 1; };
int operator()(int i){ return i; };
};
class child : private base
{
public:
auto operator()()
-> decltype(base::operator()())
{
return base::operator()();
}
auto operator()(int i)
-> decltype(base::operator()(std::declval<int>()))
{
return base::operator()(i);
}
};
Thanks for your time.
If your code is literally this, then you can exploit the fact that the protected operator() from base is also available in child, and use a simple trait:
template <typename> struct memfn_result;
template <typename C, typename R, typename ...Args>
struct memfn_result<R (C::*)(Args...)>
{
using type = R;
};
class base
{
protected:
int operator()(){ return 1; };
};
class child : private base
{
memfn_result<decltype(&child::operator())>::type a; // "a" is an "int"
};
Since base::operator()() is protected and you are using it on an object of type base rather than an object of type child you clearly can't access the member! You need to access the function call operator using an object of type child. Sadly, child is incomplete in the context where you are trying to access it, i.e., you need to an indirection:
class child
: private base {
auto static doSomeMethod()
-> decltype((std::declval<base>().*(&child::operator()))()) {
return 1;
}
};
Is there any possible way that a generic type can be used to contain a child of a base class.
From the assignment given to me, I am to create something similar to the following in structure.
template <class T>
class Fruit {
private:
int count;
int location_id;
T type;
public:
virtual void displayInfo();
};
class Apple : private Fruit<Apple> {
private:
int variety;
public:
void displayInfo() {
printf("Location %i has %i of %s in stock", location_id, count, variety);
}
};
Fruit<Apple> appleinventory[SIZE];
Basically, I think you can't have a template generic type be the same as a derived class. Am I wrong? Is there something similar that would possibly work?
Update:
For the assignment, I believe we are to use inheritance to show use of virtual functions. I've updated the code above. I think this would work, but does NOT need templates to be successful. We have not covered any advanced, redundant inheritance methods in class.
This is perfectly fine, in principle.
Read up about Curiously Recurring Template Pattern (CRTP) for more info on usage of derived class as the instantiating type in a class template that is its base, esp the example about static polymorphism which should look 'curiously' familiar.
template <class Derived> struct Base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
Derived::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
Ignoring questions of why you want to do this....you can get some of the way by doing this following:
template <class T> class Fruit
{
private:
int count;
int location_id;
T* type;
};
class Apple : private Fruit<Apple>
{
private:
int seeds;
bool red;
};
Fruit<Apple> appleinventory[SIZE];
Note the T* type is now a pointer to Apple rather than an instance of Apple.