I was trying to make a shortcut class for malloc'd unique_ptr, but I failed to extend it with default constructor. That's why I tried to make the same action on my example class, to get my hands on the error. This works perfectly:
namespace paw {
template<class T, class F>
class Cl {
public:
Cl(T* t, F f): t(t), f(f) {}
virtual ~Cl() { if (t!= 0) { f(t); } }
private:
T* t;
F f;
};
}
class ClInt : public paw::Cl<int, std::function<void(int*)>> {
public:
ClInt() : Cl(0, free) {}
ClInt(int* t) : Cl(t, free) {}
};
int main() {
ClInt clint;
}
However when I generalize ClInt class:
namespace paw {
template<class T, class F>
class Cl {
public:
Cl(T* t, F f): t(t), f(f) {}
virtual ~Cl() { if (t!= 0) { f(t); }}
private:
T* t;
F f;
};
}
template<class T>
class ClInt : public paw::Cl<T, std::function<void(T*)>> {
public:
ClInt() : Cl(0, free) {}
ClInt(T* t) : Cl(t, free) {}
};
int main() {
ClInt<int> clint;
}
i get this strange error:
error: class 'ClInt<T>' does not have any field named 'Cl'
However I cannot call superclass constructor with paw:: namespace because I get
error: expected class-name before '(' token
What is the difference and why this is not working?
Simply use the full signature for the template instances like this:
template<class T>
class ClInt : public paw::Cl<T, std::function<void(T*)>> {
public:
ClInt() : paw::Cl<T, std::function<void(T*)>>(0, free) {}
ClInt(T* t) : paw::Cl<T, std::function<void(T*)>>(t, free) {}
};
Related
Suppose to have the following class structure:
template <typename T, typename U>
class Base
{
public:
virtual ~Base<T, U>(){};
virtual U show() = 0;
protected:
T foo;
};
class DerivateA : public Base<int, int>
{
public:
DerivateA() { foo = 7; };
virtual int show() override { return foo; };
};
class DerivateB : public Base<std::string, std::string>
{
public:
DerivateB() { foo = "Hello"; };
virtual std::string show() override { return foo; };
};
Is there any way I can create a factory object with a Create() function that, based on an input value, returns a pointer to either DerivateA or DerivateB?
Not sure if I understood your issue correctly, but it could be smth like:
template<typename T, typename U>
class Base
{
protected:
explicit Base(T arg) : foo{std::move(arg)} {}
public:
virtual ~Base<T, U>() = default;
virtual U show() = 0;
protected:
T foo;
};
template<typename T>
class Derivate : public Base<T, T>
{
using base_type = Base<T, T>;
public:
explicit Derivate(const T& arg) : base_type(arg) { };
T show() override { return base_type::foo; };
};
class Factory
{
public:
template<typename T>
static Derivate<T>* create(const T& arg)
{ return new Derivate<T>{arg}; }
};
and we could use it like:
Base<int, int>* d1 = Factory::create(3);
Base<string, string>* d2 = Factory::create(string{"string"});
With IAR compiler, I have the following error:
Argument list for class template "CallbackInterface" is missing
But with VisualC++, it compiles like a charm.
What could explain it?
Heres is my callback interface
template<typename DataModel, typename... ArgumentType>
class CallbackInterface : public DataModel
{
public:
CallbackInterface() {};
~CallbackInterface() {};
CallbackInterface(ArgumentType... arg) : DataModel(arg...) {};
protected:
///Callback methods
static bool AlwaysDisplayable(DataModel* baseInstance) { return true; };
};
Here's my specialization for this interface:
template<typename DataModel, typename... ArgumentType>
class ThisCallbackInterface : public CallbackInterface<DataModel, ArgumentType...>
{
public:
ThisCallbackInterface() {};
~ThisCallbackInterface() {};
ThisCallbackInterface(ArgumentType... arg) : CallbackInterface(arg...) {};
And my final child class:
using DataType = Something;
struct DataModel
{
DataModel(){};
DataModel(DataType dataArgs){};
};
class Child: public CallbackStore<DataModel>, public ThisCallbackInterface<DataModel,DataType>
{
public:
Child(DataType dataArgs) :
CallbackStore(this),
ThisCallbackInterface(dataArgs){};
Child():
CallbackStore(nullptr),
ThisCallbackInterface(){};
~Child(){};
};
Maybe explicating the template parameters of CallbackInterface ?
ThisCallbackInterface(ArgumentType... arg)
: CallbackInterface<DataModel, ArgumentType...>(arg...)
{ } // ..............^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Why does the following fail with error: 'a_' was not declared in this scope in the context of Bar::get()?
template <typename N>
class Foo
{
public:
Foo() { }
protected:
N a_;
};
template <typename N>
class Bar : public Foo<N>
{
public:
Bar() : Foo<N>() { }
N get() { return a_; }
};
You need to use the reference this->_a
N get() { return this->a_; }
I have a diamond inheritance scheme, where the last child should be able to inherit from many different parents.
A
/|\
/ | \
B C ...
| | |
* *
D E
Now imagine I have a class D : public B, class E : public B, public C, etc. From D I want to call the same function of all its parents, which I am guaranteed exists due to the inheritance. My thought was that I could wrap this in some variadic template.
Currently I have this:
template <typename T>
class A
{
public:
A(T t) : mT(t) {}
virtual ~A() {}
virtual void doThings() = 0;
protected:
T mT;
};
template <typename T, typename A = A<T>>
class B : public A
{
public:
B(T t) : A(t) {}
virtual ~B() {}
virtual void doThings() { std::cout << "B" << std::endl; }
};
template <typename T, typename A = A<T>>
class C : public A
{
public:
C(T t) : A(t) {}
virtual ~C() {}
virtual void doThings() { std::cout << "C" << std::endl; }
};
Now I thought I could do something like this, which obviously does not work:
template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
ChildGenerator(T t) : Args(t)... {}
// The unpacking of the variadic template does not work here.
// Do I need to make it recursive somehow? How can I do that without having to instantiate new classes B and C?
void doThings() override { Args...::doThings();}
};
My hope is that I can use it like so:
int main()
{
using B = B<double>;
using C = C<double>;
B c1(0.0);
C c2(1.0);
ChildGenerator<double, B, C> c3(2.0);
c1.doThings();
c2.doThings();
c3.doThings();
}
Expected output (order does not matter):
B
C
B // <-- order of these two does not matter
C // <--
Is what I'm trying to achieve possible?
One way to iterate over the variadic bases:
template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
ChildGenerator(T t) : Args(t)... {}
void doThings() override {
int dummy[] = {0, (Args::doThings(), void(), 0)...};
static_cast<void>(dummy); // avoid warning for unused variable
}
};
or in C++17, with folding expression:
void doThings() override {
(static_cast<void>(Args::doThings()), ...);
}
Use a fold-expression (C++17):
void doThings() override { ((Args::doThings()) , ...);}
Live demo
I have a diamond inheritance scheme, where the last child should be able to inherit from many different parents.
A
/|\
/ | \
B C ...
| | |
* *
D E
Now imagine I have a class D : public B, class E : public B, public C, etc. From D I want to call the same function of all its parents, which I am guaranteed exists due to the inheritance. My thought was that I could wrap this in some variadic template.
Currently I have this:
template <typename T>
class A
{
public:
A(T t) : mT(t) {}
virtual ~A() {}
virtual void doThings() = 0;
protected:
T mT;
};
template <typename T, typename A = A<T>>
class B : public A
{
public:
B(T t) : A(t) {}
virtual ~B() {}
virtual void doThings() { std::cout << "B" << std::endl; }
};
template <typename T, typename A = A<T>>
class C : public A
{
public:
C(T t) : A(t) {}
virtual ~C() {}
virtual void doThings() { std::cout << "C" << std::endl; }
};
Now I thought I could do something like this, which obviously does not work:
template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
ChildGenerator(T t) : Args(t)... {}
// The unpacking of the variadic template does not work here.
// Do I need to make it recursive somehow? How can I do that without having to instantiate new classes B and C?
void doThings() override { Args...::doThings();}
};
My hope is that I can use it like so:
int main()
{
using B = B<double>;
using C = C<double>;
B c1(0.0);
C c2(1.0);
ChildGenerator<double, B, C> c3(2.0);
c1.doThings();
c2.doThings();
c3.doThings();
}
Expected output (order does not matter):
B
C
B // <-- order of these two does not matter
C // <--
Is what I'm trying to achieve possible?
One way to iterate over the variadic bases:
template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
ChildGenerator(T t) : Args(t)... {}
void doThings() override {
int dummy[] = {0, (Args::doThings(), void(), 0)...};
static_cast<void>(dummy); // avoid warning for unused variable
}
};
or in C++17, with folding expression:
void doThings() override {
(static_cast<void>(Args::doThings()), ...);
}
Use a fold-expression (C++17):
void doThings() override { ((Args::doThings()) , ...);}
Live demo