I'm having some trouble figuring out if I can use templated generic constraints in C++/CLI. here's an example
template<typename T>
public ref class wrapped
{
public:
T* t;
T doTthing(){return *t;}
};
Here's a simple templated managed class, wrapping an unmanaged type T. I can use this class as a constraint for a generic
// works
generic<class genclass> where genclass : wrapped<int>
public ref class testclass3
{
public:
genclass gc;
int test()
{
return gc->doTthing();
}
};
This works fine. What I can't figure out is how to preserve both the templating and the generic, i.e.
//Does Not Work!
template<typename T>
generic<class genclass> where genclass : wrapped<T>
public ref class testclass4
{
public:
genclass gc;
T test()
{
return gc->doTthing();
}
};
Is this kind of thing possible?
You can't mix templates with generics in the same declaration.
The class should either be templated or generic. See: Managed Templates
Templates are mush more expressive, so i would suggest you use them instead.
If you want to simulate a constraint (same technique would work in c++ by the way..) you could do:
template<class T, class GENCLASS>
public ref class testclass4
{
private:
typedef typename GENCLASS::wrapped<T> Constraint1;
public:
genclass gc;
T test()
{
return gc->doTthing();
}
};
If the class does not inherit from wrapped<T> then the typedef declaration will fail saying that "wrapped is not a member of GENCLASS".
Related
Consider a file main.cc with the following code:
template<typename Commodity>
class Shop
{
public:
Shop(){}
~Shop(){}
};
template<typename FuelType>
class Car
{
public:
Car(){}
virtual ~Car(){}
};
template<typename FuelType>
class Volkswagen : public Car<FuelType>
{
public:
Volkswagen(){}
~Volkswagen(){}
};
int main()
{
// this is fine...
Car<int>* myCar = new Volkswagen<int>();
delete myCar;
// ...but this isn't
Shop<Car<int>>* myCarShop = new Shop<Volkswagen<int>>();
return 0;
}
When I try to compile, I get an error:
cannot convert 'Shop<Volkswagen<int> >*' to 'Shop<Car<int> >*' in initialization...'
Now, I understand why I get this error. It's because Shop<Volkswagen<T>> in general does not have to inherit from Shop<Car<T>>.
My question is: How can I implement a structure like this? Is there a better way with classes and templates or should I, when I'm absolutely certain that Shop<Volkswagen<T>> always is a Shop<Car<T>>, attempt to explitly cast the pointer?
Edit 1: One solution could be to add a class
template<typename FuelType>
class VolkswagenShop : public Shop<Volkswagen<FuelType>>, public virtual Shop<Car<FuelType>>
{
public:
VolkswagenShop(){}
~VolkswagenShop(){}
};
and then write
Shop<Car<int>>* myCarShop = new VolkswagenShop<int>();
This compiles, but the structure has gotten complicated to a point where I, with my very limited c++ ability, am not sure if this won't cause any problems.
So, risking being too vague, will the above solution cause any obvious problems?
Template instantiation is not inheritance! foo<A> and foo<B> are two distinct and unrelated types. If you want all Shop<CARTYPE<T>> to inherit from Shop<Car<T>> then you can do that.
If it is ok to change the declaration of Shop to take 2 template parameters (and if you are not scared of template template parameters) you can do this:
template<typename FuelType>
class Car
{
public:
Car(){}
virtual ~Car(){}
};
template<typename FuelType>
class Volkswagen : public Car<FuelType>
{
public:
Volkswagen(){}
~Volkswagen(){}
};
template <template<class> class CarType,typename Commodity>
class Shop : public Shop<Car,Commodity>
{
public:
using Car_t = CarType<Commodity>;
Shop(){}
virtual ~Shop(){}
};
template <typename Commodity>
class Shop<Car,Commodity> {
virtual ~Shop(){}
};
int main()
{
// this is fine...
Car<int>* myCar = new Volkswagen<int>();
delete myCar;
// this also
Shop<Car,int>* myCarShop = new Shop<Volkswagen,int>();
delete myCarShop;
return 0;
}
However, template specialization is also not inheritance! You will need to repeat all methods in the general template and in the template <typename Commodity> class Shop<Car,Commodity> {}; specialization. To avoid code duplication you could write a ShopBase class that is not a template and provides the interface you want to use polymorphically on all shops.
PS: Mixing compile time and runtime polymorphis is possible, but I would reconsider what you really need. Taking a look at CRTP might give you some inspiration.
I have the following hierarchy pattern in various places in the codebase:
enum DerivedType {
A, B, C };
class Base {
public:
static Base* Create(DerivedType t);
};
template <DerivedType T>
class Derived : public Base {
};
The Create method returns a new object of class Derived<A>, Derived<B>, or Derived<C>, depending on its argument:
Base* Base::Create(DerivedType t) {
switch (t) {
case A: return new Derived<A>;
case B: return new Derived<B>;
case C: return new Derived<C>;
default: return NULL;
}
}
The problem is that there are many such Base -> Derived hierarchies, with essentially the same implementation of Create() copy-pasted all over the place. Is there an elegant, yet easy-to-understand way to avoid duplication here?
We can abstract away the Factory details, and rely on the client to provide us the mapping of enum to class type:
template<typename ENUM, typename T>
struct Factory
{
typedef std::map<ENUM, T*(*)()> map_type;
static map_type factoryMapping_;
static T* Create(ENUM c)
{
return factoryMapping_[c]();
}
static void Init(map_type _mapping)
{
factoryMapping_ = _mapping;
}
};
template<typename ENUM, typename T>
typename Factory<ENUM, T>::map_type Factory<ENUM,T>::factoryMapping_;
Now it's the client's job to provide us methods for creating a Base* given some enum value.
If you're willing and able to abstract away the creation of a derived class with a template, then you can save a fair bit of typing.
What I mean is, let's create a templated function to create a derived class (without any real checking for correctness):
template<typename Base, typename Derived>
Base* CreateDerived()
{
return new Derived();
}
Now I can define an enum and associated class hierarchy:
enum ClassType {A, B};
struct Foo
{
virtual void PrintName() const
{
std::cout << "Foo\n";
}
};
typedef Factory<ClassType, Foo> FooFactory ;
struct DerivedOne : public Foo
{
virtual void PrintName() const
{
std::cout << "DerivedOne\n";
}
};
struct DerivedTwo : public Foo
{
virtual void PrintName() const
{
std::cout << "DerivedTwo\n";
}
};
And then use it like so:
// set up factory
std::map<ClassType, Foo*(*)()> mapping;
mapping[A] = &CreateDerived<Foo, DerivedOne>;
mapping[B] = &CreateDerived<Foo, DerivedTwo>;
FooFactory::Init(mapping);
// Use the factory
Foo* f = FooFactory::Create(A);
f->PrintName();
Live Demo
Of course this simplifies your problem a bit, namely moving the factory details out of the base class and ignoring for a minute that the children themselves are templated. Depending on how hard it is in your domain to create a good CreateDerived function for each type, you may not end up saving a ton of typing.
EDIT: We can modify our Create function to return NULL by taking advantage of std::map::find. I omitted it for brevity. If you concerned about performance, then yes, an O(log n) search is slower asymptotically than a simple switch, but I strongly doubt this will wind up being the hot path.
You could make it a template
template<typename Base, typename Derive, template<Derive> class Derived>
Base* Base::Create(Derive t) {
switch (t) {
case Derive::A: return new Derived<Derive::A>;
case Derive::B: return new Derived<Derive::B>;
case Derive::C: return new Derived<Derive::C>;
default: return nullptr;
}
}
but that assumes that there are only ever A, B, and C in struct enum Derive.
Instead of using a C++ style enum you could use a Java style enum where each value is a singleton of a class derived from a common base.
Then define a set of pure virtual functions on the base class that create the desired flavour of derived class, and implement them appropriately in each of the singletons.
Then instead of switch (t) ... you can use t->createDerived().
Or to put it more succinctly: replace switch with polymorphism.
I tried to create an SSCE, because this usually also helps to find an issue early on. However, I can't seem to find a solution for this, so I would like to know if it is possible to define an argument which is an unspecified template class pointer.
I have an interface defined, and a parser class, which should handle the implementation details for xerces (like transcoding and all this overhead). The interface class would be designed to create the objects from the (SAX)parser, but without having to deal with the xerces library.
In Java I know I could use an unspecified generic type argument like this:
class Parser
{
public Parser(IGenericInterface<?> oImpl) {};
}
And basically I'm would like to know how this can be done in C++. In the below example I get a compiler error on the line declaring the interface variable because it is missing the type. But of course in the class declaration the type is unknown and should get assigned during runtime as shown in main.
#include <iostream>
#include <string>
template <class T>
class IGenericInterface
{
public:
IGenericInterface() {};
virtual ~IGenericInterface() {};
virtual T *createInstance(void) = 0;
};
template <class T>
class Implementation : public IGenericInterface<T>
{
public:
Implementation() {};
virtual ~Implementation() {};
T *createInstance(void)
{
T * t = new T;
return t;
}
};
class Parser
{
public:
Parser(IGenericInterface *oImpl) { mImpl = oImpl; };
virtual ~Parser() { delete mImpl; };
void doSomething(void) { do whatrever is needed; t = createInstance(); };
private:
IGenericInterface *mImpl;
};
int main()
{
Parser *p = new Parser(new Implementation<int>());
sleep(3);
return 0;
}
So how do I have to define the Parser constructor to make it pass an arbitrary interface argument?
C++ is a static language, so any types must be resolved at compile time. Hence, what you are doing in java cannot be done in the same way in C++. Instead, you use either dynamic polymorphism (using inheritance) or "static polymorphism", using templates (resolved at compile time) with CRTP.
Mixing static and dynamic polymorphism is a no go (exemptions might apply)
template <class T>
class IGenericInterface
{
public:
IGenericInterface() {};
virtual ~IGenericInterface() {};
virtual T *createInstance(void) = 0;
};
And your use of pointers is a nightmare.
Since apparently a generic like in Java can not be implemented in C++, I found a different solution which also allows me to keep the details of the parser separated.
The functions that should have been in the Interface class are now moved to the parser class as virtual abstract functions. The I can define a template which derives from the parser, thus be forced to implement the virtual functions, which basically is what I wanted.
The pattern looks like this now:
template <class T>
class ISerialization
{
public:
virtual ~ISerialization(void) {};
public:
virtual std::string serialize(void) = 0;
virtual bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) = 0;
};
class parser
{
void parsing(void) { abstract_function(); }
virtual void abstract_function() = 0;
};
class implementation : public ISerialization<Task>, public parser
{
std::string serialize(void) {};
bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) {};
void abstract_function() { specific implementation goes here};
};
I have an interface IEnumerable for template classes of List<>, Array<> and Dictionary<>. I was hoping to use typedef to get their templated types T.
I was hoping to do the following.
class IEnumerable
{
public:
virtual typedef int TemplateType;
}
And then override in inherited member, but you cant make a virtual typedef. So is there any other way that i could get the type of an unknown template class (IEnumerable is not template)?
Well, here is what is discussed in the comments in case somebody with the same question later finds this.
Basically, you want to do something similar to C#'s List<>, Array<>, IEnumerable and IEnumerator. However, you don't want to have to create a generic parent class Object because it may mean that you'll need to dynamic_cast every time.
Additionally, you don't want to make IEnumerable a template because you don't want to have to know the type when using the collection.
In fact, with C++11, you can make IEnumerable a template and not have to know the type by using the implicit type keyword auto, which is the C++11 equivalent of c#'s var keyword.
So to do this, what you can do is:
template <class T>
class IEnumerable {
public:
virtual IEnumerator<T> getEnumerator() = 0;
// and more stuff
}
then
template <class T>
class List : public IEnumerable<T> {
public:
virtual IEnumerator<T> getEnumerator() {
return ListEnumerator<T>(this);
}
}
and
template <class T>
class ListEnumerator : public IEnumerator<T> {
public:
T getNext(); // or something to this effect
// and more stuff
}
Finally, when it comes to using it, you can do:
List<int> myList;
auto i = myList.getEnumerator();
int z = i.getNext()+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.