Ignore template parameter - c++

Is there a way in the code below to say that I don't care what the V parameter is in void watch(event<T, _> &e)
#include <stdlib.h>
#include <stdio.h>
enum events_a {
A_1,
A_2,
};
enum events_b {
B_1,
B_2,
};
template<typename T, T V>
class event {
public:
T id(void) {
return V;
}
};
template<typename T>
class event_loop {
public:
void watch(event<T, _> &e) {
};
};
class a1 : public event<enum events_a, A_2>
{
};
int
main (int argc, char *argv[])
{
a1 a;
printf("%d\n", a.id());
return 0;
}
What I'm trying to do is that users should be forced to subclass event<T,V> and be forced to give T and V.
However the subclass of event_loop<T>, specifically the method watch, should work with all event<T> regardless of their V.
I don't want to template just the watch function as I want the user to be forced to subclass event_loop.
Bonus achievement if I can somehow make sure all subclasses of event<T> have a unique V. Shooting for the stars... :D

Just create a template argument for it and ignore it.
template<typename T, typename Ignore>
class event_loop {
public:
void watch(event<T, Ignore> &e) {
};
};
You could also template just the function, if you want only the function to be templated
template<typename T>
class event_loop {
public:
template<typename Ignore>
void watch(event<T, Ignore> &e) {
};
};

You could specify a default argument for V and static assert like the way below:
enum events_a {
A_1 = 1,
A_2,
};
enum events_b {
B_1 = 1,
B_2,
};
template<typename T, T V = {}>
class event {
static_assert(V != 0, "You should Define a V");
public:
T id() {
return V;
}
};
template<typename T>
struct event_loop {
void watch(event<T> &e) {}
};
class a1 : public event<enum events_a, A_2> { };
Live Demo

Related

Is possible to get type a child class type from base class?

I need something like this:
template <typename T>
class A
{
public:
T commonData;
TYPEOF_CHILD_CLASS *test(T data)
{
return new CHILD_CLASS(data);
}
};
template <typename T>
class B : public A<T>
{
public:
T bdata;
B(T data)
{
bdata = data;
}
};
template <typename T>
class C : public A<T>
{
public:
T cdata;
C(T data)
{
cdata = data;
}
};
int main(int argc, char const *argv[])
{
auto a = C<int>(1).test(2);
return 0;
}
Is possible to define TYPEOF_CHILD_CLASS in c++? Before I used D. In D it works with:
R (this R) test(T data)
{
return new R(data);
}
...
void main()
{
auto a = new C!A(1).test(2);
}
It is a template. Does the c++ have a similar method? Maybe can I set type also via a template? Or may be I determine typename via typeid?
Thanks #Some programmer dude #463035818_is_not_a_number. In according to this link it works.
template <class T, typename TT>
class A
{
public:
TT commonData;
T *test(TT data)
{
return new T(data);
}
};
template <typename T>
class B : public A<B<T>, T>
{
public:
T bdata;
B(T data)
{
bdata = data;
}
};
template <typename T>
class C : public A<C<T>, T>
{
public:
T cdata;
C(T data)
{
cdata = data;
}
};
int main(int argc, char const *argv[])
{
auto a = C<int>(1).test(2);
return 0;
}

C++11 Variadic Class Handler Manager

I'm trying to create a template class (event class manager) that will instantiate multiple event class objects. I'm able to get it work for one class, but not able to get it work in the variadic case. I'm trying to get the class_mgr class to take in a list of event classes. For each one, I would like an entry in the std::array.
#include <array>
class handler {
public:
void handle() {}
};
enum event_class_types {
eclass1 = 0,
eclass2,
num_classes,
};
class base {
};
template<typename handlerType>
class event_class1 : public base {
public:
event_class1(handlerType& handler) :
handler_(handler) {}
private:
handlerType& handler_;
};
template<typename handlerType>
class event_class2 : public base {
public:
event_class2(handlerType& handler) :
handler_(handler) {}
private:
handlerType& handler_;
};
namespace map {
template<typename handlerType>
struct event_class1 {
using type = ::event_class1<handlerType>;
static constexpr int id = eclass1;
};
template<typename handlerType>
struct event_class2 {
using type = ::event_class2<handlerType>;
static constexpr int id = eclass2;
};
}
//TODO: variadic
template<typename handlerType, template< typename T> class mapTypes>
class event_class_mgr
{
public:
event_class_mgr(handlerType& handler) :
handler_(handler)
{
add_class();
}
private:
void add_class( )
{
my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_);
}
handlerType handler_;
std::array< base*, event_class_types::num_classes> my_classes_{};
};
int main(int argc, char** argv) {
handler my_handler;
event_class_mgr<handler, map::event_class1> cm(my_handler);
//Trying to make this variadic, to pass multiple types to my handler
//class_mgr<handler, map::event_class1, map::event_class2> cm(my_handler);
//alternatively, i could just pass the enums?
//class_mgr<handler, event_eclass1, event_eclass2> cm(my_handler);
return 0;
};
If I got what you mean, it's straightforward.
Just turn the class template declaration to:
template<typename handlerType, template< typename T> class... mapTypes>
class event_class_mgr {
// ...
}
Then update the add_class member function:
void add_class( )
{
using accumulator_type = int[];
accumulator_type accumulator = { (my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_), 0)... };
(void)accumulator;
}
Using C++17 and thus fold expressions would have reduced the boilerplate, but you explicitly marked the question as C++11, so...
See it up and running on wandbox.
As a side note, in C++17 you can write add_class as:
void add_class( )
{
((my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_)), ...);
}

how to get outer class name from inner enum

basicly what i want to do is written in code. so , is there a way with templates or with something else get outer class name in global function ? is there a way to get this code work?
#include <iostream>
class A
{
public:
enum class B
{
val1,
val2
};
typedef B InnerEnum;
static void f(InnerEnum val)
{
std::cout << static_cast<int>(val);
}
};
template <typename T1>
void f(typename T1::InnerEnum val)
{
T1::f(val);
}
int main()
{
A::InnerEnum v = A::InnerEnum::val1;
f(v);
return 0;
}
You may create trait for that and manually feed it:
template <typename T>
struct outer_class;
template <>
struct outer_class<A::B> { using type = A;};
And then
template <typename E>
void f(E val)
{
using T = typename outer_class<E>::type;
T::f(val);
}

Can I pass a certain value to member constructor based on template argument?

Here is a simplified version of a class template (it has subclasses) that I have:
template<class T>
class Bitmap
{
public:
typedef T pixeltype;
Bitmap(const T* PixelData) : Data(/* PixelFormat enum based on T */) { ... }
virtual ~Bitmap() { ... }
...
protected:
Texture Data;
};
The template argument T to Bitmap can be either class A<X> or A<Y> (possibly a few more in the future), where A is a class template as well. Based on T, aka pixeltype, I need to pass one of the enum values PixelFormatX or PixelFormatY to the constructor of Data, which takes an int.
Is this possible? If not, how could I go about implementing what I described?
For completeness, here's what the subclasses basically look like:
template<class T>
class ColorizableBitmap : public Bitmap<T>
{
public:
typedef T pixeltype;
ColorizableBitmap(const T* PixelData) : Bitmap<T>(PixelData) { ... }
...
};
I generally use a traits struct for that:
template<class T>
struct BitmapTraits
{
};
template<class T, class traits = BitmapTraits<T> >
class Bitmap
{
public:
typedef T pixeltype;
Bitmap(const T* PixelData) : Data(traits::PixelFormat) { ... }
virtual ~Bitmap() { ... }
...
protected:
Texture Data;
};
Then use template specialization to define the traits of each class:
template<>
struct BitmapTraits< A<X> >
{
static const int PixelFormat = PixelFormatX;
};
template<>
struct BitmapTraits< A<Y> >
{
static const int PixelFormat = PixelFormatY;
};
You could do something like:
enum A {
x,y
};
class X {
public:
static A a;
};
class Y {
public:
static A a;
};
A X::a = x;
A Y::a = y;
template <class T>
class Bitmap {
public:
Bitmap(): Data(T::a) {
}
A Data;
};
Edited:
In that case you could do something like:
enum A {
x,y
};
template <const A V>
class X {
public:
static A a;
};
template <const A V>
A X<V>::a = V;
template <class T>
class Bitmap {
public:
Bitmap(): Data(T::a) {
}
A Data;
};
int main() {
Bitmap<X<x>> b;
}
Edited 2:
If I undestrood you right you have two nested class now and still you can do something like:
enum A {
x,y
};
template <typename T>
class B {
public:
typedef T t;
};
template <const A V>
class X {
public:
static A a;
};
template <const A V>
A X<V>::a = V;
template <class T>
class Bitmap {
public:
Bitmap(): Data(T::t::a) {
}
A Data;
};
int main() {
Bitmap<B<X<x>>> b;
}
The alternative is (as Remy Lebeau suggested) template specialization.

boost concept check operator() overload

template <typename T, typename C>
class CSVWriter{
template <typename PrinterT>
void write(std::ostream& stream, const PrinterT& printer){
}
};
I want to check whether there exists at least two overloads PrinterT::operator()(T*) and PrinterT::operator()(C*)
PrinterT may or may not inherit from std::unary_function
What concept Checking Classes I need to use here ?
(I am not using C++11)
You can use something like that
#include <iostream>
#include <boost/concept/requires.hpp>
#include <boost/concept/usage.hpp>
template <class Type, class Param>
class has_operator_round_brackets_with_parameter
{
public:
BOOST_CONCEPT_USAGE(has_operator_round_brackets_with_parameter)
{
_t(_p);
}
private:
Type _t;
Param _p;
};
struct X {};
struct Y {};
struct Test1
{
void operator() (X*) const { }
};
struct Test2: public Test1
{
void operator() (X*) const { }
void operator() (Y*) const { }
};
template <class T, class C>
struct CSVWriter
{
template <class PrinterT>
BOOST_CONCEPT_REQUIRES(
((has_operator_round_brackets_with_parameter<PrinterT, T*>))
((has_operator_round_brackets_with_parameter<PrinterT, C*>)),
(void)) write(std::ostream& stream, const PrinterT& printer)
{
}
};
int main()
{
CSVWriter<X, Y> w;
// w.write<Test1>(std::cout, Test1()); // FAIL
w.write<Test2>(std::cout, Test2()); // OK
return 0;
}