如何编写一个不断敲击输出的包装器?
How to write a wrapper that keeps rapping the output?
基本上,我想做的是在一些抽象 class 上有一个包装器,然后用相同的包装器 class 包装那个 [=38= 的任何成员函数的输出].继续这样做,以便始终包裹所有对象。
喜欢(预设代码)
wrap<set(1..10)> (multiply,2)
(divide,3)
(plus,5)
(inverse)
(collect first 10)
.unwrap()
除了最后一行,上面的所有行都输出了一些东西的换行。现在似乎意义不大,但我相信我们可以在上面应用有趣的东西,比如:
wrap<someClass> dat;
dat.splitIntoThreads(2)
(thingA) .clone()
(thingB) (thing1)
(thingC) (thing2)
(thingD) (thing3)
.nothing() (thing4)
.sync() .exit()
.addMerge()
这是我的包装代码:
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');
}
正在运行(gcc、c++0x)。但是当我用以下内容替换第 6,7 行时(实际包装结果)
wrap<L> operator() (L(T::*f)(R...),R...r){
return wrap<L>(a.f(r...));
编译器只是说:创建指向非class类型成员函数的指针"int"。
我该如何解决这个问题?有什么更好的方法吗?继承是一种方式,但由于我们可能在一个包装中有变量实例,我认为它没有用。
编辑
这是我的测试class
struct testClass{
int f(int a,char b){
return a+b;
}
};
我使用 wrap L 而不是 wrap T 的原因是 return 类型可能并不总是 T。
看来错误出在您的 testclass
定义中。请检查以下示例。
此外,在 operator() 中换行可以作为参考返回。我认为没有必要创建用于 () 链接的临时文件。
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;
};
一个测试class来积累数字。
class testClass {
int m;
public:
testClass(int _m) : m{_m}{}
int f(int x) {
m += x;
std::cout << ' ' << m;
return m;
}
};
用法示例:
int main(){
wrap<testClass> a{0};
a(&testClass::f,13)(&testClass::f, 11)(&testClass::f,3)(&testClass::f, 21);
}
每一步累加总和的输出:
13 24 27 48
您可以尝试这样的操作:
#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;
}
基本上,我想做的是在一些抽象 class 上有一个包装器,然后用相同的包装器 class 包装那个 [=38= 的任何成员函数的输出].继续这样做,以便始终包裹所有对象。
喜欢(预设代码)
wrap<set(1..10)> (multiply,2)
(divide,3)
(plus,5)
(inverse)
(collect first 10)
.unwrap()
除了最后一行,上面的所有行都输出了一些东西的换行。现在似乎意义不大,但我相信我们可以在上面应用有趣的东西,比如:
wrap<someClass> dat;
dat.splitIntoThreads(2)
(thingA) .clone()
(thingB) (thing1)
(thingC) (thing2)
(thingD) (thing3)
.nothing() (thing4)
.sync() .exit()
.addMerge()
这是我的包装代码:
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');
}
正在运行(gcc、c++0x)。但是当我用以下内容替换第 6,7 行时(实际包装结果)
wrap<L> operator() (L(T::*f)(R...),R...r){
return wrap<L>(a.f(r...));
编译器只是说:创建指向非class类型成员函数的指针"int"。
我该如何解决这个问题?有什么更好的方法吗?继承是一种方式,但由于我们可能在一个包装中有变量实例,我认为它没有用。
编辑
这是我的测试class
struct testClass{
int f(int a,char b){
return a+b;
}
};
我使用 wrap L 而不是 wrap T 的原因是 return 类型可能并不总是 T。
看来错误出在您的 testclass
定义中。请检查以下示例。
此外,在 operator() 中换行可以作为参考返回。我认为没有必要创建用于 () 链接的临时文件。
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;
};
一个测试class来积累数字。
class testClass {
int m;
public:
testClass(int _m) : m{_m}{}
int f(int x) {
m += x;
std::cout << ' ' << m;
return m;
}
};
用法示例:
int main(){
wrap<testClass> a{0};
a(&testClass::f,13)(&testClass::f, 11)(&testClass::f,3)(&testClass::f, 21);
}
每一步累加总和的输出:
13 24 27 48
您可以尝试这样的操作:
#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;
}