Basically, what I want to do is to hava a wrapper on some abstract class, then have the same wrapper class wrap around the output of any member function of that class. Keep doing that so that all objects are always wrapped.
Like (presudocode)
wrap<set(1..10)> (multiply,2)
(divide,3)
(plus,5)
(inverse)
(collect first 10)
.unwrap()
All lines above except the last line outputs wrap of something. It seems to be meanling less for now, but I believe then we can apply interesting things on it like:
wrap<someClass> dat;
dat.splitIntoThreads(2)
(thingA) .clone()
(thingB) (thing1)
(thingC) (thing2)
(thingD) (thing3)
.nothing() (thing4)
.sync() .exit()
.addMerge()
Here is my code for wrap:
template<class T>
struct wrap{
wrap(){}
wrap(T b){a=b;}
template<class L,class...R>
L operator() (L(T::*f)(R...),R...r){
return a.f(r...);
}
T a;
};
int main(){
wrap<testClass> a;
a(&testClass::f,13,'a');
}
It's working (gcc, c++0x). But when I replace the 6,7th line with the following (to actually wrap the result)
wrap<L> operator() (L(T::*f)(R...),R...r){
return wrap<L>(a.f(r...));
The compiler just sais: creating pointer to member function of non-class type "int".
How can I fix this? Is there any better to do this? Inheritence is one way but since we might have variable instance in one wrap, I think it's not useful.
EDIT
Here's my test class
struct testClass{
int f(int a,char b){
return a+b;
}
};
The reason why I'm using wrap L instead of wrap T is that the return type might not always be T.
You can try something like this:
#include <iostream>
#include <type_traits>
template<class T, bool = false>
struct wrap{
template <typename... Args>
wrap(Args&&... args) : a{std::forward<Args>(args)...} {};
template<class L, class...R>
wrap<L,std::is_fundamental<L>::value> operator() (L(T::*f)(R...),R...r){
return wrap<L,std::is_fundamental<L>::value > {(a.*f)(r...)};
}
T a;
};
template<class T>
struct wrap <T,true>{
template <typename... Args>
wrap(Args&&... args) : a{std::forward<Args>(args)...} {}
template<class L, class...R>
wrap<L,std::is_fundamental<L>::value> operator() (L(*f)(T a, R...), R...r){
return wrap<L,std::is_fundamental<L>::value > {f(a, r...)};
}
T a;
};
class testClass {
int m;
public:
testClass(int _m) : m{_m}{}
int multiAdd(int x, char y) {
m += x + y;
return m;
}
};
int add(int a, char b)
{
return a+b;
}
int main(){
wrap<testClass> a{0};
std::cout << a(&testClass::multiAdd,0,'d')(add,'a').a<<std::endl;
wrap<int, true> b{3};
std::cout << b(add,'a').a<<std::endl;
}
cpp.sh/6icg
It seems the error is in your testclass definition. Please check the below example.
Also, wrap in the operator() can be returned as reference. I don't see any need to create temporaries to be used for () chaining.
template<class T>
struct wrap{
template <typename... Args>
wrap(Args&&... args) : a{std::forward<Args>(args)...} {};
template<class L, class...R>
wrap<T>& operator() (L(T::*f)(R...),R...r){
a.f(r...);
return *this; //returning reference to current wrap object.
}
T a;
};
A test class to accumulate numbers.
class testClass {
int m;
public:
testClass(int _m) : m{_m}{}
int f(int x) {
m += x;
std::cout << ' ' << m;
return m;
}
};
An usage example:
int main(){
wrap<testClass> a{0};
a(&testClass::f,13)(&testClass::f, 11)(&testClass::f,3)(&testClass::f, 21);
}
Output of sum accumulated at each step:
13 24 27 48
Related
Suppose that a class has a member function which should accept either a double(double) function or a class instance with a "MyStructFunc" public member function as an argument:
#include<functional>
#include <type_traits>
struct Caller
{
// (1.)
double call(std::function<double(double)> func) { return func(1); }
// (2.)
template<typename T>
double call(const T& S) { return S.MyStructFunc(2); }
};
So, for example, we can pass
double myFunc(double x) { return x * x * x; }
or
struct myStruct
{
double MyStructFunc(double x) const { return x * x; }
};
like this:
int main()
{
Caller c;
myStruct ms;
c.call(myFunc);
c.call(ms);
}
Unfortunately, I get an error. Could you please help me make it work? Thank you for your help!
function pointer is not a std::function, so your template method is a better match.
You might use SFINAE to restrict your template method:
// (2.)
template<typename T>
auto call(const T& S) -> decltype(S.MyStructFunc(2)) { return S.MyStructFunc(2); }
Demo
I am writing an Abstract Factory using C++ templates and was hit by a small obstacle. Namely, a generic class T may provide one or more of the following ways to construct objects:
static T* T::create(int arg);
T(int arg);
T();
I am writing the abstract factory class so that it can automatically try these three potential constructions in the given order:
template <class T>
class Factory {
public:
T* create(int arg) {
return T::create(arg); // first preference
return new T(arg); // this if above does not exist
return new T; // this if above does not exist
// compiler error if none of the three is provided by class T
}
};
How do I achieve this with C++ template? Thank you.
Something along this line should work:
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<int N> struct tag: tag<N-1> {};
template<> struct tag<0> {};
class Factory {
template<typename C>
auto create(tag<2>, int N) -> decltype(C::create(N)) {
return C::create(N);
}
template<typename C>
auto create(tag<1>, int N) -> decltype(new C{N}) {
return new C{N};
}
template<typename C>
auto create(tag<0>, ...) {
return new C{};
}
public:
template<typename C>
auto create(int N) {
return create<C>(tag<2>{}, N);
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
It's based on sfinae and tag dispatching techniques.
The basic idea is that you forward the create function of your factory to a set of internal functions. These functions test the features you are looking for in order because of the presence of tag and are discarded if the test fail. Because of sfinae, as long as one of them succeeds, the code compiles and everything works as expected.
Here is a similar solution in C++17:
#include <type_traits>
#include <iostream>
#include <utility>
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<typename C> constexpr auto has_create(int) -> decltype(C::create(std::declval<int>()), bool{}) { return true; }
template<typename C> constexpr auto has_create(char) { return false; }
struct Factory {
template<typename C>
auto create(int N) {
if constexpr(has_create<C>(0)) {
std::cout << "has create" << std::endl;
return C::create(N);
} else if constexpr(std::is_constructible_v<C, int>) {
std::cout << "has proper constructor" << std::endl;
return new C{N};
} else {
std::cout << "well, do it and shut up" << std::endl;
(void)N;
return C{};
}
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
Thanks to #StoryTeller and #Jarod42 for the help in this difficult morning.
See it up and running on wandbox.
Okay, thanks to the answer by #skypjack I was able to come up with a more compatible solution that works with pre c++11 compilers. The core idea is the same, i.e. using tag dispatching for ordered testing. Instead of relying on decltype, I used sizeof and a dummy class for SFINAE.
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<class C, int=sizeof(C::create(0))> struct test_1 { typedef int type; };
template<class C, int=sizeof(C(0))> struct test_2 { typedef int type; };
template<class C, int=sizeof(C())> struct test_3 { typedef int type; };
template<int N> struct priority: priority<N-1> {};
template<> struct priority<0> {};
class Factory {
template<typename C>
C* create(priority<2>, typename test_1<C>::type N) {
return C::create(N);
}
template<typename C>
C* create(priority<1>, typename test_2<C>::type N) {
return new C(N);
}
template<typename C>
C* create(priority<0>, typename test_3<C>::type N) {
return new C();
}
public:
template<typename C>
C* create(int N) {
return create<C>(priority<2>(), N);
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
Not sure if it is even possible to stuff the sizeof part into the private function signatures; if so, we can get rid of the dummy classes as well.(failed) The slightly ugly part is to use constants (0 in this case) for sizeof operator, which may get tricky if the constructors take arguments of very complicated types.
If I have a struct like:
struct Thing
{
int x;
int y;
bool a;
bool b;
}
Then I can create a Thing object by doing: Thing t {1,2,true,false};. However, if I have a tuple then I am doing something like:
std::tuple<int, int, bool, bool> info = std::make_tuple(1,2,true,false);
Thing t { std::get<0>(info), std::get<1>(info).. // and so on
Is there a better way to do this?
We can create a generic factory function for creating aggregates from tuple-like types (std::tuple, std::pair, std::array, and arbitrary user-defined tuple-like objects in a structured bindings world†):
template <class T, class Tuple, size_t... Is>
T construct_from_tuple(Tuple&& tuple, std::index_sequence<Is...> ) {
return T{std::get<Is>(std::forward<Tuple>(tuple))...};
}
template <class T, class Tuple>
T construct_from_tuple(Tuple&& tuple) {
return construct_from_tuple<T>(std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}
);
}
which in your case would be used as:
std::tuple<int, int, bool, bool> info = std::make_tuple(1,2,true,false);
Thing t = construct_from_tuple<Thing>(info); // or std::move(info)
This way, Thing can still be an aggregate (don't have to add constructor/assignments), and our solution solves the problem for many, many types.
As an improvement, we could add SFINAE to both overloads to ensure that they're not callable with invalid tuple types.
†Pending accepting wording of how decomposition will work, the qualified call to std::get<Is> may need to be changed to an unqualified call to get<Is> which has special lookup rules. For now, this is moot, since it's 2016 and we don't have structured bindings.
Update: In C++17, there is std::make_from_tuple().
If you are using c++14 you could make use of std::index_sequence creating helper function and struct as follows:
#include <tuple>
#include <utility>
struct Thing
{
int x;
int y;
bool a;
bool b;
};
template <class Thi, class Tup, class I = std::make_index_sequence<std::tuple_size<Tup>::value>>
struct Creator;
template <class Thi, class Tup, size_t... Is>
struct Creator<Thi, Tup, std::index_sequence<Is...> > {
static Thi create(const Tup &t) {
return {std::get<Is>(t)...};
}
};
template <class Thi, class Tup>
Thi create(const Tup &t) {
return Creator<Thi, Tup>::create(t);
}
int main() {
Thing thi = create<Thing>(std::make_tuple(1,2,true,false));
}
And the version without additional class (with one additional function):
#include <tuple>
#include <utility>
struct Thing
{
int x;
int y;
bool a;
bool b;
};
template <class Thi, class Tup, size_t... Is>
Thi create_impl(const Tup &t, std::index_sequence<Is...>) {
return {std::get<Is>(t)...};
}
template <class Thi, class Tup>
Thi create(const Tup &t) {
return create_impl<Thi, Tup>(t, std::make_index_sequence<std::tuple_size<Tup>::value>{});
}
int main() {
Thing thi = create<Thing>(std::make_tuple(1,2,true,false));
}
Yet another this time tricky version with just one helper function:
#include <tuple>
#include <utility>
struct Thing
{
int x;
int y;
bool a;
bool b;
};
template <class R, class T, size_t... Is>
R create(const T &t, std::index_sequence<Is...> = {}) {
if (std::tuple_size<T>::value == sizeof...(Is)) {
return {std::get<Is>(t)...};
}
return create<R>(t, std::make_index_sequence<std::tuple_size<T>::value>{});
}
int main() {
Thing thi = create<Thing>(std::make_tuple(1,2,true,false));
}
You may use std::tie:
Thing t;
std::tie(t.x, t.y, t.a, t.b) = info;
Here are other ways:
struct Thing
{
Thing(){}
Thing(int A_, int B_, int C_, int D_) //1
: A(A_), B(B_), C(C_), D(D_) {}
Thing(std::tuple<int,int,bool,bool> tuple) //3
: A(std::get<0>(tuple)), B(std::get<1>(tuple)),
C(std::get<2>(tuple)), D(std::get<3>(tuple)) {}
void tie_from_tuple(std::tuple<int,int,bool,bool> tuple) //4
{
std::tie(A,B,C,D) = tuple;
}
int A;
int B;
bool C;
bool D;
};
inline Thing tuple_to_thing(const std::tuple<int,int,bool,bool>& tuple) //2
{
return Thing{std::get<0>(tuple), std::get<1>(tuple),
std::get<2>(tuple), std::get<3>(tuple)};
}
int main()
{
auto info = std::make_tuple(1,2,true,false);
//1 make a constructor
Thing one(info);
//2 make a conversion function
Thing second = tuple_to_thing(info);
//3 don't use tuple (just use the struct itself if you have to pass it)
Thing three{1,2,true,false};
//4 make member function that uses std::tie
Thing four;
four.tie_from_tuple(info);
}
Provide an explicit constructor and assignment operator:
struct Thing
{
int x;
int y;
bool a;
bool b;
Thing() { }
Thing( int x, int y, bool a, bool b ): x(x), y(y), a(a), b(b) { }
Thing( const std::tuple <int, int, bool, bool> & t )
{
std::tie( x, y, a, b ) = t;
}
Thing& operator = ( const std::tuple <int, int, bool, bool> & t )
{
std::tie( x, y, a, b ) = t;
return *this;
}
};
Hope this helps.
Getting fancy with C++17 template argument deduction and using a proxy object (usage example at bottom):
#include <tuple>
using namespace std;
template <class Tuple>
class FromTuple {
// static constructor, used to unpack argument_pack
template <class Result, class From, size_t... indices>
static constexpr Result construct(index_sequence<indices...>, From&& from_tuple) {
return { get<indices>(forward<
decltype(from_tuple.arguments)>(from_tuple.arguments))... };
}
// used to select static constructor
using Indices = make_index_sequence<
tuple_size_v< remove_reference_t<Tuple> >>;
public:
// construct with actual tuple types only for parameter deduction
explicit constexpr FromTuple(const Tuple& arguments) : arguments(arguments) {}
explicit constexpr FromTuple(Tuple&& arguments) : arguments(move(arguments)) {}
// implicit cast operator delegates to static constructor
template <class Result>
constexpr operator Result() { return construct<Result>(Indices{}, *this); }
private:
Tuple arguments;
};
struct Thing { int x; int y; bool a; bool b; };
int main() {
std::tuple<int, int, bool, bool> info = std::make_tuple(1,2,true,false);
Thing thing0((Thing)FromTuple(info));
Thing thing1{(Thing)FromTuple(info)};
FromTuple from_info(info);
Thing thing2(from_info); // only way to avoid implicit cast operator
Thing thing3{(Thing)from_info};
return 0;
}
This generalizes to any class or struct, not just Thing. Tuple arguments will be passed into the constructor.
This question already has answers here:
How to pass a template function in a template argument list
(2 answers)
Closed 6 years ago.
For the life of me, I can't get this simple piece of arcane template magic to work:
template<typename T, int a, int b>
int f(T v){
return v*a-b; // just do something for example
}
template<typename T, int a, int b, template<typename,int,int> class func>
class C{
int f(){
return func<T,a,b>(3);
}
};
int main(){
C<float,3,2, f> c;
}
Is this possible to do without involving functors?
f is supposed to be a class - you have a function.
See below:
// Class acts like a function - also known as functor.
template<typename T, int a, int b>
class f
{
int operator()(T v)
{
return v*a-b; // just do something for example
}
};
template<typename T, int a, int b, template<typename,int,int> class func>
class C
{
int f()
{
return func<T,a,b>(3);
}
};
int main()
{
C<float,3,2, f> c;
}
... And the adapted version if you need to port legacy code (Adapts the function to a class template):
#include <iostream>
template<typename T, int a, int b>
int f(T v)
{
std::cout << "Called" << std::endl;
return v*a-b; // just do something for example
}
template<typename T, int a, int b, template<typename,int,int> class func>
struct C
{
int f()
{
return func<T,a,b>(3);
}
};
template <class T, int a, int b>
struct FuncAdapt
{
T x_;
template <class U>
FuncAdapt( U x )
: x_( x )
{}
operator int() const
{
return f<T,a,b>( x_ );
}
};
int main()
{
C<float,3,2, FuncAdapt > c;
c.f();
}
You can solve it through a little trickery:
template<typename T, int a, int b>
int f(T v){
return v*a-b; // just do something for example
}
template<typename T, int, int>
using func_t = int (*)(T);
template<typename T, int a, int b, func_t<T, a, b> func>
class C{
int f(){
return func(3);
}
};
C<float,3,2, f<float, 3, 2>> c;
First you need a type-alias for the function (func_t above), and you unfortunately need to duplicate the template arguments in the declaration of c.
No, it's not. Even the syntax:
template <typename T, int a, int b, template <typename, int, int> class func>
^^^^^
shows that an argument for a template template parameter must be a class template.
The reason your compiler is complaining is that you're passing a function (f) as a class to the last template parameter for class C.
Since you cannot pass a function as a template parameter, you should use function pointers or functors. And functors are definitely the cleaner way to do this.
So, although it's possible to achieve what you want without using functors, you really shouldn't try to.
If you want to use function pointers you will be looking at something like this:
template<typename T, int a, int b, int (*func)(T)>
class C{
int f(){
return (*func)(3);
}
};
int main(){
C< float,3,2,&f<float,3,2> > c;
}
In that case I don't think you would be able to eliminate the code duplication in the declaration of c, but I might be wrong.
I am creating a templated class D<N>, with a method (operator(), in this case) that returns different types, depending on the value of N.
I could only make this work by creating two separate class declarations, but this came at the cost of a lot of code duplication. I also tried to create a common base class to throw the common stuff into, but I couldn't get the constructor to inherit right and don't know how idiomatic that would be as well...
#include <cstdio>
template <int N>
struct D{
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
D<N-1> operator()(int x){
D<N-1> d(yell(x));
return d;
}
};
template <>
struct D<1>{
int s;
D(int x): s(x){}
int yell(int x){
printf("N=%d, %d\n", 1, s+x);
return s+x;
}
int operator()(int x){
return yell(x);
}
};
int main()
{
D<2> f(42);
printf("%d\n", f(1)(2));
return 0;
}
How can I make my code better looking?
You can use the Curiously Recurring Template Pattern.
template<int N, template<int> typename D> struct d_inner {
D<N-1> operator()(int x) {
return D<N-1>(static_cast<D<N>*>(this)->yell(x));
}
};
template<template<int> typename D> struct d_inner<1, D> {
int operator()(int x) {
return static_cast<D<1>*>(this)->yell(x);
}
};
template <int N> struct D : public d_inner<N, D> {
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
};
Not that I see the utility- or purpose- of this particular object being templated, it could easily not be.
I'm not sure it is better looking: but it avoids source code duplication :
// Find a name for this ...
template<int N, template<int M> class X>
struct foo {
typedef X<N> type;
};
template< template<int M> class X >
struct foo<0,X> {
typedef int type;
};
template <int N>
struct D{
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
typename foo<N-1,D>::type
operator()(int x){
return typename foo<N-1,D>::type(yell(x));
}
};