I want to be able to perfect forward argument to derived class through base class. The only idea I have is to implement not virtual perfect forwarding function in base class and have virtual functions overloads for lvalues and rvalues. Something like this:
Consider:
#include <iostream>
#include <memory>
#include <string>
class base_t
{
public:
virtual ~base_t() = default;
template<typename T>
void perfect_forward(T&& value)
{
process(std::forward<T>(value));
}
protected:
virtual void process(const std::string& value) = 0;
virtual void process(std::string&& value) = 0;
};
class derived_t : public base_t
{
protected:
void process(const std::string& value) override final
{
std::cout << "derived_t::process(const lvalue&)" << std::endl;
}
void process(std::string&& value) override final
{
std::cout << "derived_t::process(rvalue&&)" << std::endl;
}
};
int main(int argc, const char* argv[])
{
const std::string lvalue;
auto rvalue = []() { return std::string(); };
std::unique_ptr<base_t> base(new derived_t);
base->perfect_forward(lvalue);
base->perfect_forward(rvalue());
}
But this has a little meaning, because instead of template perfect_forward function in base class I can simply provide two overload for virtual process. How I can avoid code duplicate in derived class for process method and use std::forward there through base_t interface?
If you don't want to take the std::string by value, there is an approach using a mixin class, but it requires changing your class hierachy:
template<class D>
class process_mixin : public base_t {
protected:
void process(std::string const& value) override final {
return ((D*)this)->do_process(value);
}
void process(std::string&& value) override final {
return ((D*)this)->do_process(std::move(value));
}
};
class derived_t : public process_mixin<derived_t> {
protected:
template<typename T>
void do_process(T&& value) {
}
friend process_mixin<derived_t>;
};
process_mixin only has to be written once. From then on anything that derives from base_t can instead derive from process_mixin and you get a perfect forwarding interface.
Related
I am trying to understand the behavior of "Type Erasure" by using std::make_shared. The basic idea is to use a class Object to wrap some different classes, such as class Foo and class Bar.
I write the following code, and it does work.
// TypeErasure.cpp
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Base
{
public:
virtual ~Base() {}
virtual std::string getName() const = 0;
};
template< typename T >
struct Derived : Base
{
public:
explicit Derived(const T&& t) : objD(t) {}
std::string getName() const override
{
return objD.getName();
}
private:
T objD;
};
class Object
{
public:
template <typename T>
explicit Object(T&& t)
: objPtr(std::make_shared<Derived<T>>(std::forward<T>(t))) {}
std::string getName() const
{
return objPtr->getName();
}
std::shared_ptr<const Base> objPtr;
};
void printName(std::vector<Object> vec)
{
for (auto v: vec) std::cout << v.getName() << std::endl;
}
class Bar
{
public:
std::string getName() const
{
return "Bar";
}
};
class Foo
{
public:
std::string getName() const
{
return "Foo";
}
};
int main()
{
std::vector<Object> vec{Object(Foo()), Object(Bar())};
printName(vec);
}
but when I change "struct Derived : Base" into "class Derived : Base", it shows the following error.
error: no matching function for call to 'std::shared_ptr::shared_ptr(std::shared_ptr)'|
The code is as following.
// TypeErasure.cpp
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Base
{
public:
virtual ~Base() {}
virtual std::string getName() const = 0;
};
template< typename T >
class Derived : Base
{
public:
explicit Derived(const T&& t) : objD(t) {}
std::string getName() const override
{
return objD.getName();
}
private:
T objD;
};
class Object
{
public:
template <typename T>
explicit Object(T&& t)
: objPtr(std::make_shared<Derived<T>>(std::forward<T>(t))) {}
std::string getName() const
{
return objPtr->getName();
}
std::shared_ptr<const Base> objPtr;
};
void printName(std::vector<Object> vec)
{
for (auto v: vec) std::cout << v.getName() << std::endl;
}
class Bar
{
public:
std::string getName() const
{
return "Bar";
}
};
class Foo
{
public:
std::string getName() const
{
return "Foo";
}
};
int main()
{
std::vector<Object> vec{Object(Foo()), Object(Bar())};
printName(vec);
}
What is the root cause of this error?
Is it about the difference between class and struct?
Is it because class is a reference and struct is a value?
The only real difference between a class and a struct in C++ is that, for a struct, the default member access and inheritance is public, whereas, for a class, the default is private.
So, to make your code work for the class Derived template, just make its inheritance of Base public:
template< typename T >
class Derived : public Base { // public inheritance
public:
//...
Such public inheritance gives the Derived class access to the Base class constructors.
Alternatively, to make your struct template case fail – most likely with the exact same error message(s) – you can make its inheritance of Base private:
template< typename T >
struct Derived : private Base { // private inheritance - fails to compile!
public:
//...
I'm trying to implement factory method pattern in my QT project following this example: https://www.codeproject.com/Articles/363338/Factory-Pattern-in-Cplusplus
#include <QCoreApplication>
#include <QDebug>
class IAnimal
{
public:
virtual int GetNumberOfLegs() const = 0;
virtual void Speak() = 0;
virtual void Free() = 0;
};
typedef IAnimal* (__stdcall *CreateAnimalFn)(void);
// IAnimal implementations
class Cat : public IAnimal
{
public:
int GetNumberOfLegs() const { return 4; }
void Speak() { qDebug() << "Meow" << endl; }
void Free() { delete this; }
static IAnimal * __stdcall Create() { return new Cat(); }
};
class Dog : public IAnimal
{
public:
int GetNumberOfLegs() const { return 4; }
void Speak() { qDebug() << "Woof" << endl; }
void Free() { delete this; }
static IAnimal * __stdcall Create() { return new Dog(); }
};
Factory class:
// Factory for creating instances of IAnimal
class AnimalFactory
{
private:
AnimalFactory();
AnimalFactory(const AnimalFactory &) { }
AnimalFactory &operator=(const AnimalFactory &) { return *this; }
typedef QMap<QString,CreateAnimalFn> FactoryMap;
FactoryMap m_FactoryMap;
public:
~AnimalFactory() { m_FactoryMap.clear(); }
static AnimalFactory *Get()
{
static AnimalFactory instance;
return &instance;
}
void Register(const QString &animalName, CreateAnimalFn pfnCreate);
IAnimal *CreateAnimal(const QString &animalName);
};
AnimalFactory::AnimalFactory()
{
Register("Cat", &Cat::Create);
Register("Dog", &Dog::Create);
}
void AnimalFactory::Register(const QString &animalName, CreateAnimalFn pfnCreate)
{
m_FactoryMap[animalName] = pfnCreate;
}
IAnimal *AnimalFactory::CreateAnimal(const QString &animalName)
{
FactoryMap::iterator it = m_FactoryMap.find(animalName);
if( it != m_FactoryMap.end() )
return it.value();
return NULL;
}
However I am encountering such an error:
cannot convert 'IAnimal* (__attribute__((__stdcall__)) *)()' to 'IAnimal*' in return
return it.value();
Only existing anwser (Insert function pointer into QMap (Qt)) suggests making Create() functions static which doesn't seem to help.
I will be very grateful for any piece of advice.
That's a little bit complicated. You're writing C++, so you shouldn't be copying Java. C++ is way more expressive here.
You won't need the explicit Create/Free methods - the compiler can generate them for you, automatically.
You definitely need a virtual destructor, otherwise the interface will be useless. Any class you intend to derive from must have a virtual destructor, with very few specialized exceptions from this rule.
All implementations of virtual methods should be declared override, including the destructor, but not virtual as that'd violate DRY.
The classes can carry their names, so that the factory can register them just by knowing their types. This is an optional behavior of the factory.
#include <QtCore>
class IAnimal {
public:
virtual int GetNumberOfLegs() const = 0;
virtual QString Speaks() = 0;
virtual ~IAnimal() {}
};
class Cat : public IAnimal {
public:
int GetNumberOfLegs() const override { return 4; }
QString Speaks() override { return QStringLiteral("Meow"); }
static auto className() { return "Cat"; }
};
class Dog : public IAnimal {
public:
int GetNumberOfLegs() const override { return 4; }
QString Speaks() override { return QStringLiteral("Woof"); }
static auto className() { return "Dog"; }
};
Now we can have a generic factory. Note that all sane C++ container types manage their data. You don't need to explicitly clear them on destruction. We're leveraging C++11. The Register method will only accept types that derive from Interface, and that method automatically generates a construction function using the lambda expression.
The lifetime of the instance should be controlled explicitly by instantiating it in main().
#include <type_traits>
#include <typeindex>
#include <map>
template <class Interface> class Factory {
template <class C, class T = void> struct enable_if_I :
std::enable_if<std::is_base_of<Interface, C>::value, T> {};
using create_fn = Interface* (*)();
std::map<QByteArray, create_fn, std::less<>> m_creators;
std::map<std::type_index, QByteArray> m_names;
static Factory *&instance_ref() { // assume no inline static yet
static Factory *m_instance;
return m_instance;
}
Factory(const Factory &) = delete;
Factory &operator=(const Factory &) = delete;
public:
Factory() {
Q_ASSERT(!instance());
instance_ref() = this;
}
virtual ~Factory() { instance_ref() = {}; }
In general, registration requires the type and name of the derived class. This presupposes nothing about whether the class has a className() member. The factory stores both the factory function and the name. This allows name look up without having className as a virtual method of the interface.
template <class T> typename enable_if_I<T>::type Register(const QByteArray &name) {
m_creators[name] = +[]()->Interface* { return new T(); };
m_names[{typeid(T)}] = name;
}
When class names are known, we can leverage them to register one or more classes, given just their types.
template <class T1> typename enable_if_I<T1>::type Register() {
this->Register<T1>(T1::className());
}
template <class T1, class T2, class...T> typename enable_if_I<T1>::type Register() {
this->Register<T1>(T1::className());
this->Register<T2, T...>();
}
The instance creation methods are optimized not to copy the name given, no matter the format. This is why we use the std::map<K, V, std::less<>> map with a transparent comparator. QByteArray provides operator< that takes various types on the right-hand side, and to exploit this, the type of the key (here: name) must reach the comparator.
template <typename T> static Interface *CreateA(T &&t) {
return instance() ? instance()->Create(std::forward<T>(t)) : nullptr;
}
Interface *Create(QLatin1String name) const { return Create(name.data()); }
template <typename T> Interface *Create(T &&name) const;
static const QByteArray &NameOfA(const Interface * obj);
const QByteArray &NameOf(const Interface *) const;
static Factory *instance() { return instance_ref(); }
};
template <class Interface>
template <typename T> Interface *Factory<Interface>::Create(T &&name) const {
auto it = m_creators.find(name);
return (it != m_creators.end()) ? it->second() : nullptr;
}
namespace detail {
const QByteArray & null() { static const QByteArray n; return n; }
}
template <class Interface>
const QByteArray &Factory<Interface>::NameOfA(const Interface *obj) {
return instance() ? instance()->NameOf(obj) : detail::null();
}
template <class Interface>
const QByteArray &Factory<Interface>::NameOf(const Interface *obj) const {
auto it = m_names.find(typeid(*obj));
return (it != m_names.end()) ? it->second : detail::null();
}
The generic factory takes the interface and concrete types and registers them all in the constructor. This makes building the factories simple.
template <class Interface, class ...Types>
class GenericFactory : public Factory<Interface> {
public:
GenericFactory() {
this->template Register<Types...>();
}
};
using AnimalFactory = GenericFactory<IAnimal, Cat, Dog>;
Example of use, with asserts to indicate desired behavior. Note that to destroy the objects, one merely has to delete their instance. The compiler will generate the calls.
int main() {
Q_ASSERT(!AnimalFactory::instance());
{
AnimalFactory animals;
Q_ASSERT(AnimalFactory::instance());
auto *dog1 = AnimalFactory::CreateA("Dog");
Q_ASSERT(dynamic_cast<Dog*>(dog1));
Q_ASSERT(AnimalFactory::NameOfA(dog1) == Dog::className());
Q_ASSERT(dog1->Speaks() == QStringLiteral("Woof"));
auto *dog2 = AnimalFactory::CreateA(QLatin1String("Dog"));
Q_ASSERT(dynamic_cast<Dog*>(dog2));
auto *cat = AnimalFactory::CreateA("Cat");
Q_ASSERT(dynamic_cast<Cat*>(cat));
Q_ASSERT(cat->Speaks() == QStringLiteral("Meow"));
Q_ASSERT(AnimalFactory::NameOfA(cat) == Cat::className());
delete cat;
delete dog2;
delete dog1;
}
Q_ASSERT(!AnimalFactory::instance());
}
I am using a composite design pattern and I want to clone my objects from my composite class. I tried to make a generic clone method in my component class, but when I try to send the concrete type of my object to the generic (template) method, 'typeof' and 'typeid' returns the abstract class type. So, when I try to use new typeof(object), I see the error
"invalid new-expression of abstract class type 'Component'".
My compiler is MigGW 32 bits.
As I can't know the type of my object, I can't use dynamic_cast.
Am I using typeof/typeid wrongly or should I use other keyword to know the concrete object type?
#include <iostream>
#include <vector>
#include <typeinfo>
class Component
{
public:
template <typename Tdest> typename std::remove_cv<typename std::remove_pointer<Tdest>::type>::type* clone() const
{
typedef typename std::remove_cv<typename std::remove_pointer<Tdest>::type>::type NO_POINTER_NOR_CV;
return new typeof(NO_POINTER_NOR_CV)(*dynamic_cast<const NO_POINTER_NOR_CV*>(this));
}
virtual void manipulateComponents() = 0;
virtual void add(Component* comp) = 0;
protected:
std::vector<const Component*> _v;
};
class Leaf : public Component
{
void manipulateComponents() override { return; }
void add(Component* comp) override { return; }
};
class Composite : public Component
{
public:
void manipulateComponents() override
{
for(auto component : _v)
{
std::cout << typeid(component).name() << std::endl; // print PK9Component
component->clone<typeof(component)>();
/* ... */
}
}
void add(Component* comp) override { _v.push_back(comp); }
};
int main(int argc, char* argv[])
{
Component* l = new Leaf();
Component* c = new Composite();
Component* parent = new Composite();
parent->add(l);
parent->add(c);
parent->manipulateComponents();
}
You are not getting the details of the derived type using typeid since you are using it on a pointer. Dereference the pionter in the call to get the name of the derived type.
Change
std::cout << typeid(component).name() << std::endl; // print PK9Component
// PK9Component seems indicate that it is a pointer to a Component.
to
std::cout << typeid(*component).name() << std::endl;
// ^^
If you want a clone method, you have to add a virtual function to return it, as in:
struct A
{
virtual std::unique_ptr<A> clone() const = 0;
A() = default;
A(A const&) = default;
A(A&&) = default;
A& operator=(A&&) = default;
A& operator=(A const&) = default;
virtual ~A() = default;
};
struct B : A
{
std::unique_ptr<A> clone() const override
{
assert(typeid(*this) == typeid(B));
return std::make_unique<B>(*this);
}
};
The assert protects (at run time) against deriving from B w/o overriding the clone() method.
The C++ Committee is working on A polymorphic value-type for C++, but that won't be available for a while.
No amount of typeof magic in your clone method will give you the type of a subclass of a non-templated class. It can give you the type of an instantiated template, but the only possible instantiation of your clone method here is in your base class. Subclassing doesn't redefine template methods.
If you really want to, you can use template methods in subclassing if you're willing to use the "Curiously Recurring Template Pattern". There's a sample clone implementation on Wikipedia, which I'll quote here:
// Base class has a pure virtual function for cloning
class Shape {
public:
virtual ~Shape() {};
virtual Shape *clone() const = 0;
};
// This CRTP class implements clone() for Derived
template <typename Derived>
class Shape_CRTP : public Shape {
public:
virtual Shape *clone() const {
return new Derived(static_cast<Derived const&>(*this));
}
};
// Nice macro which ensures correct CRTP usage
#define Derive_Shape_CRTP(Type) class Type: public Shape_CRTP<Type>
// Every derived class inherits from Shape_CRTP instead of Shape
Derive_Shape_CRTP(Square) {};
Derive_Shape_CRTP(Circle) {};
With CRTP, you may do:
template <typename Derived>
class IClonable
{
public:
virtual ~IClonable() = default;
std::unique_ptr<Derived> clone() const {
return std::unique_ptr<Derived>(cloneImpl());
}
protected:
virtual Derived* cloneImpl() const = 0;
};
template <typename Derived, typename Base>
class Clonable : public Base
{
public:
std::unique_ptr<Derived> clone() const { // Hide Base::clone to return static type.
return std::unique_ptr<Derived>(static_cast<Derived*>(cloneImpl()));
}
protected:
Clonable* cloneImpl() const { return new Derived{static_cast<const Derived&>(*this)}; }
};
And then:
class Component : public IClonable<Component>
{
public:
virtual void manipulateComponents() = 0;
virtual void add(const Component&) = 0;
};
class Leaf : public Clonable<Leaf, Component>
{
public:
void manipulateComponents() override {}
void add(const Component&) override {}
};
class Composite : public Clonable<Composite, Component>
{
public:
void manipulateComponents() override
{
for (const auto* component : _v)
{
auto cloned = component->clone(); // std::unique_ptr<Component>
/* ... */
}
}
void add(const Component& comp) override { _v.push_back(&comp); }
protected:
std::vector<const Component*> _v;
};
With possible usage:
Leaf l;
Composite c;
auto parent = c.clone(); // std::unique_ptr<Composite>
parent->add(l);
parent->add(c);
parent->manipulateComponents();
Suppose we have a base class and a bunch of derived classes. Is there any way or mechanism to know all the derived class names programmatically?
Maybe reflection is a good idea, but it's not available on C++. I suppose there will be some kind of template that can finish this job during compilation.
class Base{
public:
virtual void print(){
// This function should print all the names of derived class.
}
virtual Base* getInstance(string class_name){
// This function should return an instance related to the class name.
}
};
class Derived_1 : public Base{ // Suppose we have 100 Derived_X classes,
// so we don't want to add its name to a list manually.
};
int main(){
Base base;
base.print(); // This should print the name of all the derived class.
base.getInstance("Derived_1"); // This should return an instance of Derived_1
return 0;
}
This solution is based on the fact that it seems you are actually looking for a factory. It uses a small macro to ease classes registration, hope you don't care about it.
factory.h
#ifndef __FACTORY_H__
#define __FACTORY_H__
#include <map>
#include <functional>
#include <string>
#include <iostream>
template<class B>
class Factory {
std::map<std::string, std::function<B*()>> s_creators;
public:
static Factory<B>& getInstance() {
static Factory<B> s_instance;
return s_instance;
}
template<class T>
void registerClass(const std::string& name) {
s_creators.insert({name, []() -> B* { return new T(); }});
}
B* create(const std::string& name) {
const auto it = s_creators.find(name);
if (it == s_creators.end()) return nullptr; // not a derived class
return (it->second)();
}
void printRegisteredClasses() {
for (const auto &creator : s_creators) {
std::cout << creator.first << '\n';
}
}
};
#define FACTORY(Class) Factory<Class>::getInstance()
template<class B, class T>
class Creator {
public:
explicit Creator(const std::string& name) {
FACTORY(B).registerClass<T>(name);
}
};
#define REGISTER(base_class, derived_class) \
Creator<base_class, derived_class> s_##derived_class##Creator(#derived_class);
#endif
example.cpp
#include "factory.h"
#include <memory>
class Base {
public:
virtual void printName() const { std::cout << "Base\n"; }
};
class Derived1 : public Base {
public:
virtual void printName() const override { std::cout << "Derived1\n"; }
};
REGISTER(Base, Derived1);
class Derived2 : public Base {
public:
virtual void printName() const override { std::cout << "Derived2\n"; }
};
REGISTER(Base, Derived2);
int main() {
std::cout << "Registered classes:" << std::endl;
FACTORY(Base).printRegisteredClasses();
std::cout << "---" << std::endl;
std::unique_ptr<Base> derived1(FACTORY(Base).create("Derived1"));
derived1->printName();
return 0;
}
Note: requires C++11.
For the getInstance you can declare it a template (needs C++14). To get all the names of the derived classes in the program you probably have to resort to some preprocessor hack.
#include <type_traits>
class Base
{
public:
virtual ~Base () = default;
template < typename T,
typename = std::enable_if_t<std::is_base_of<Base, T>::value, void>
>
T getInstance() { return T{}; }
};
class Derived : public Base {};
class NotDerived {};
int main(){
Base base;
base.getInstance<Derived>();
// error: no matching member function for call to 'getInstance'
//base.getInstance<NotDerived>();
}
Regarding the name of the derived classes, I propose a solution based on a BaseList class/struct, with a static std::set (or other container) of names, a template Base class/struct, that inherit from BaseList and whose template parameter is the derived class (CRTP style) and (to semplify the construction of the derived classes/struct, a C-style macro (I know... macros are distilled evil... but sometimes...) to create the declaration of the derived classes/structs with a necessary static method, that declare the name of the derived class/struct, and a member (that activate the registration of the name).
The following is a full example (unfortunately is a C++11 one)
#include <set>
#include <string>
#include <iostream>
struct BaseList
{
static std::set<std::string> const & derList (std::string const & dn)
{
static std::set<std::string> dl;
if ( dn.size() )
dl.insert(dn);
return dl;
}
static void print ()
{
std::cout << "derived names: ";
for ( auto const & dn : derList("") )
std::cout << dn << ", ";
std::cout << std::endl;
}
};
template <typename Der>
struct Base : public BaseList
{
static std::size_t setNameInList ()
{ return derList(Der::name()).size(); }
static std::size_t id;
};
template <typename Der>
std::size_t Base<Der>::id = setNameInList();
#define setDerived(nameDer) \
struct nameDer : public Base<nameDer>\
{ \
std::size_t idc { id }; \
static std::string name () \
{ return #nameDer; }
setDerived(Derived_1)
// other elements
};
setDerived(Derived_2)
// other elements
};
setDerived(Derived_3)
// other elements
};
int main()
{
BaseList::print();
}
Regarding the getInstance() problem, the only solution that I can imagine is the same solution proposed by Enry Menke (+1), so I suggest that you get the instance through a template type parameter.
here's my problem.
I have a template abstract class RandomVariable with pure virtual function operator()()
template<T>
class RandomVariable<T> {
public:
virtual T operator()() = 0;
/* other stuff */
protected:
T value;
}
I also have a template abstract class Process with pure virtual function operator()()
template<T>
class Process<T> {
public:
typedef std::pair<double, T> state;
typedef std::list<state> result_type;
virtual result_type operator()() = 0;
/* other stuff */
protected:
result_type trajectory;
}
I can easily write a method returning generating a path and returning the last value of my trajectory.
T GenerateTerminalValue() {
this->operator()();
return value.back().second;
};
But it would be much better if, instead of returning type T my function actually returned a functor (ideally derived from RandomVariable) with overloaded operator() generating a path and returning the last value of the trajectory. My best try only led to a Segmentation Fault.
What would be a good way to do this? Thanks.
What about using std::function?
#include <functional>
template<typename T>
class MyClass {
public:
std::function<T()> GenerateTerminalValueFunc() {
return [this]() {
this->operator()();
return value.back().second;
};
}
...
};
Update: If you want to derive from RandomVariable you could try something like this:
#include <memory>
template<typename T>
class TerminalValueOp : public RandomVariable<T>
{
private:
MyClass<T>* obj_;
public:
TerminalValueOp(MyClass<T>* obj) : obj_(obj) {}
T operator()() {
obj->operator()();
return obj->value.back().second;
}
...
};
template<typename T>
class MyClass {
public:
std::shared_ptr<RandomVariable<T>> GenerateTerminalValueOp() {
return std::make_shared<TerminalValueOp<T>>(this);
}
...
};