Is there a way to automatically create one method per variadic template argument?
For example, in the code below, I want to be forced to override void x(a &v) and void x(b &v) in class i:
#include <type_traits>
#include <stdlib.h>
#include <stdio.h>
class a {
};
class b {
};
template <typename ...T>
class t {
public:
virtual void x(T &v) = 0;
};
class i : public t<a, b>
{
};
int
main (int argc, char *argv[])
{
i ii;
return 0;
}
You can make a t_impl that holds the virtual function for a single T like
template <typename T>
class t_impl
{
public:
virtual void x(T &v) = 0;
};
and then t would inherit from it like
template <typename ...T>
class t : t_impl<T>... // can use public, protected or private inheritance
{
public:
using t_impl<T>::x...; // used to import t_impl<T>::x into the public space
// any additional common members
};
Instead of making t a variadic template, just template it on a single type:
template <typename T>
class t {
public:
virtual void x(T &v) = 0;
};
and inherit base classes like this instead:
class i : public t<a>, t<b>
{
virtual void x(a &v) {}
virtual void x(b &v) {}
};
Here's a demo.
Related
Context:
I have been trying to use Dietmar Kühl's delegate class from this answer in a way that only the owner class could activate it, and I almost achieved it.
The code is the following:
// Example program
#include <algorithm>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
class Entity;
struct EvArgs {
Entity* Origin;
EvArgs(){
}
};
template <typename Signature>
struct delegate;
template <typename Args>
struct delegate<void(Args*)>
{
struct base {
virtual ~base() {}
virtual void do_call(Args* args) = 0;
};
template <typename T>
struct call : base {
T d_callback;
template <typename S>
call(S&& callback) : d_callback(std::forward<S>(callback)) {}
void do_call(Args* args) {
this->d_callback(std::forward<Args*>(args));
return;
}
};
std::vector<std::unique_ptr<base>> d_callbacks;
std::vector<std::unique_ptr<base>> d_tmp_callbacks;
delegate(delegate const&) = delete;
void operator=(delegate const&) = delete;
public:
delegate() {
if (!std::is_base_of<EvArgs, Args>::value)
throw "specified type is not derived class from EvArgs\n";
}
~delegate() {
d_callbacks.clear();
d_tmp_callbacks.clear();
}
template <typename T>
delegate& operator+= (T&& callback) {
this->d_callbacks.emplace_back(new call<T>(std::forward<T>(callback)));
return *this;
}
template <typename T>
delegate& operator<< (T&& callback) {
this->d_tmp_callbacks.emplace_back(new call<T>(std::forward<T>(callback)));
return *this;
}
};
template<typename Signature>
struct action_delegate;
template<typename Args>
struct action_delegate<void(Args*)> : public delegate<void(Args*)>{
delegate<void(Args*)>& getBase(){
return *static_cast<delegate<void(Args*)>*>(this);
}
void operator()(Args* args) {
for (auto& callback : this->d_callbacks) callback->do_call(args);
for (auto& callback : this->d_tmp_callbacks) callback->do_call(args);
this->d_tmp_callbacks.clear();
delete args;
}
};
class instance{
private:
action_delegate<void(EvArgs*)> _collision;
public:
delegate<void(EvArgs*)>& collision = _collision.getBase();
};
int main(){
instance i;
i.collision << [](EvArgs* a){
std::cout << "random calling\n";
};
//i want to prohibit this:
(static_cast< action_delegate<void(EvArgs*)>& >(i.collision))(new EvArgs());
}
Problem:
As the action_delegate is a private member, only the instance class can call its activation with operator(). And as delegate is public, operator <<() and operator +=() are accessible outside the class.
The problem is that there is a way to cast delegate into action_delegate, thus it's possible to activate the delegate with operator() outside the class. I really want to avoid that.
The original creator of this concept is accessible through the link at the start of the commentary body.
#include <iostream>
#include <array>
#include <vector>
using namespace std;
// Currently I have code much like this one:
template <const uint32_t N>
using VectorN = array<double, N>;
template <const uint32_t N>
class ITransformable {
public:
virtual vector<VectorN<N>>& positions() = 0;
};
class SomeTransformer {
public:
template <const uint32_t N>
void operator()(ITransformable<N>& transformable) const {
/* implementation */
}
};
// Then I want to create interface like this.
template <const uint32_t N>
class ITransformer {
public:
virtual void operator()(ITransformable<N>& transformable) const = 0;
};
// And finally implement it for SomeTransformer:
//
// Notice that class is not template, this is intentional.
//
// class SomeTransformer : public ITransformer<N> {
// public:
// virtual void operator()(ITransformable<N>& transformable) const {
// /* implementation */
// }
// }
Actually, now it seems impossible to me. Otherwise this class would inherit
indefinite number of interface specializations...
But still, is it possible, at least for finite number of dimensions N?
template <template <typename> class C> seems to be related, but I can't figure out how to apply this.
EDIT
What I want is something like this:
class SomeTransformer :
public ITransformer<2>,
public ITransformer<3>,
public ITransformer<4>,
...,
public ITransformer<N> {
/* ... */
};
For any N ever used in code. This seems impossible, as I said.
You can achieve what you want or nearly that. Here's what I propose:
#include <type_traits>
#include <utility>
template<std::size_t N>
struct ITransformer {};
template<class T>
class SomeTransformer_h { };
template<std::size_t... Indices>
class SomeTransformer_h<
std::integer_sequence<std::size_t, Indices...>> :
public ITransformer<1 + Indices>... { };
template<std::size_t N>
class SomeTransformer : public SomeTransformer_h<
std::make_index_sequence<N>
> { };
int main() {
SomeTransformer<5> a;
ITransformer<1>& ref = a;
ITransformer<4>& ref2 = a;
ITransformer<5>& ref3 = a;
}
Now for any N it will make SomeTransformer inherit all ITransformer from 1 to N.
Since N is not declared anywhere, you cannot use it. You need something like:
class SomeTransformer : public ITransformer<5> {
public:
virtual void operator()(ITransformable<5>& transformable) const {
/* implementation */
}
};
or make it a template class:
template <uint32_t N>
class SomeTransformer : public ITransformer<N> {
public:
virtual void operator()(ITransformable<N>& transformable) const {
/* implementation */
}
};
UPDATE
There is no dynamic inheritance in C++. Therefore, what you want to achieve is not possible.
I have a template class Field<T> which inherits from a non-template abstract base class AbstractField to be able to store all different kinds of Field<T> * types in a std::vector<AbstractField *>. My setup is as follows:
#include <vector>
class AbstractField
{
public:
virtual ~AbstractField() {};
// Something similar to: template<class T> T getValue() const; ?
};
template<class T>
class Field : public AbstractField
{
private:
T d_;
public:
Field(T d) : d_(d) {}
T getValue() const { return d_; }
};
int main()
{
AbstractField *f = new Field<double>(0.1);
// How to call: f->getValue(); ?
return 0;
}
I was wondering what would be the most natural way to call f->getValue() since I can't use a virtual template member function in the AbstractField class. As far as possible, I would prefer not using boost. Any hints are welcome!
EDIT:
Corrected std::vector<Field<T> > to std::vector<AbstractField *>. Sorry for the confusion.
Maybe this:
template <typename> struct Field;
struct AbstractField
{
virtual ~AbstractField() {}
template <typename T> T getValue()
{
return dynamic_cast<Field<T>&>(*this)->get();
}
};
template <typename T> struct Field : AbstractField
{
T & get();
// ...
};
I'm writing a wrapper for some benchmark code and want to execute the same code for every templated class type in an already templated function.
There is the benchmark class:
template<class T>
class Benchmark : public Interface, public T {
virtual void Execute();
}
And as class T I want to use a type that is basically only there for initializing class variables e.g.
template<class S>
struct GenericBench {
GenericBench();
S var1, var2, var3;
};
The question now: is it somehow possible to define a specialized function Execute for every mutation of GenericBench for this kind of class inheritance constelation?
template<>
void Benchmark<GenericBench>::Execute() {
// my benchmark code
}
A main call would then look something like this:
myBench->Execute<GenericBench<int>>();
The following code compiled and linked in g++
struct Interface { };
template<class T>
class Benchmark: public Interface, public T {
public:
virtual ~Benchmark() { }
virtual void Execute();
};
template<class S>
struct GenericBench {
GenericBench() { }
S var1, var2, var3;
};
// Specialization of the class
template<class S>
class Benchmark<GenericBench<S> >: public Interface, public GenericBench<S> {
public:
virtual ~Benchmark() { }
virtual void Execute() {
// do things
}
};
int main(int argc, char **argv) {
Benchmark<GenericBench<int> > myBench;
myBench.Execute();
}
Since you said that you want to define specialized responses on basis of type you are working on... making function template and then specializing it will help.
Following is an examples
(Apologies for not using example u provided.. I just want to show the approach. Let me know if it works for you)
template <class S> class myData {
public:
};
namespace mySpecializedFunction {
template<class P> void someFunction(P check) {std::cout<<"3333\n";return;}
template<> void someFunction(myData<int> check) {std::cout<<"4444\n";return;}
template<> void someFunction(myData<float> check) {std::cout<<"5555\n";return;}
}
template <class T> class myClass: public T {
public:
template <class Q> void someFunction( Q check) { mySpecializedFunction::someFunction(check); return ; }
};
And Using it like this...
myData<int> d1;
myData<float> d2;
myClass< myData<int> > c1;
c1.someFunction(d1);
myClass< myData<float> > c2;
c2.someFunction(d2);
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;
}