简体   繁体   English

如何编写一个不断敲击输出的包装器?

[英]How to write a wrapper that keeps rapping the output?

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) 喜欢(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). 它正在工作(gcc,c ++ 0x)。 But when I replace the 6,7th line with the following (to actually wrap the result) 但是当我用以下内容替换第6,7行时(实际包装结果)

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". 编译器只是sais:创建指向非类型“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. 我使用wrap L而不是wrap T的原因是返回类型可能并不总是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 cpp.sh/6icg

It seems the error is in your testclass definition. 似乎错误在您的测试testclass定义中。 Please check the below example. 请查看以下示例。

Also, wrap in the operator() can be returned as reference. 另外,可以返回operator()中的wrap作为引用。 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 13 24 27 48

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM