Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;函数装饰器 我正在寻找一种在C++中装饰函数或lambda的方法。目标是在函数调用之前和之后执行一些操作。正如我所看到的,最接近使用的是std::function,但它需要有其参数的类型 class FunctionDecorator { public: FunctionDecorator( std::function func ) : m_func( func ) void operator()() { // do some stuff prior to function call m_func(); // do stuff after function call } private: std::function m_func; };_C++_Templates_C++11 - Fatal编程技术网

C++;函数装饰器 我正在寻找一种在C++中装饰函数或lambda的方法。目标是在函数调用之前和之后执行一些操作。正如我所看到的,最接近使用的是std::function,但它需要有其参数的类型 class FunctionDecorator { public: FunctionDecorator( std::function func ) : m_func( func ) void operator()() { // do some stuff prior to function call m_func(); // do stuff after function call } private: std::function m_func; };

C++;函数装饰器 我正在寻找一种在C++中装饰函数或lambda的方法。目标是在函数调用之前和之后执行一些操作。正如我所看到的,最接近使用的是std::function,但它需要有其参数的类型 class FunctionDecorator { public: FunctionDecorator( std::function func ) : m_func( func ) void operator()() { // do some stuff prior to function call m_func(); // do stuff after function call } private: std::function m_func; };,c++,templates,c++11,C++,Templates,C++11,如果按模板类型可以在std::function中使用,并且当我传递指向函数的指针或std::bind的结果时,它可以以某种方式推断出来,那就太好了。 这样的事情在C++中是可能的吗?< /p> < p>只是走完整的模板,没有STD::函数: template< typename Func > class FunctionDecorator { public: FunctionDecorator( Func func ) : m_func( std::move(func)

如果按模板类型可以在std::function中使用,并且当我传递指向函数的指针或std::bind的结果时,它可以以某种方式推断出来,那就太好了。
这样的事情在C++中是可能的吗?< /p> < p>只是走完整的模板,没有STD::函数:

template< typename Func >
class FunctionDecorator
{
public:
  FunctionDecorator( Func func )
    : m_func( std::move(func) )
  {}

  void operator()()
  {
    // do some stuff prior to function call
    m_func();
    // do stuff after function call
  }

private:
  Func m_func;
};

template< typename Func >
FunctionDecorator<Func> decorate(Func func) {
  return FunctionDecorator<Func>(std::move(func));
}
模板
类函数装饰器
{
公众:
函数装饰器(Func Func)
:m_func(标准::移动(func))
{}
void运算符()()
{
//在函数调用之前做一些事情
m_func();
//在函数调用之后做一些事情
}
私人:
Func mu Func;
};
模板
函数装饰器装饰(Func Func){
返回函数decorator(std::move(func));
}

嗯。我可能有可能也可能没有做得过火

#include <type_traits>
#include <utility>
#include <iostream>

template <class T>
struct RetWrapper {
    template <class Tfunc, class... Targs>
    RetWrapper(Tfunc &&func, Targs &&... args)
    : val(std::forward<Tfunc>(func)(std::forward<Targs>(args)...)) {}

    T &&value() { return std::move(val); }

private:
    T val;
};

template <>
struct RetWrapper<void> {
    template <class Tfunc, class... Targs>
    RetWrapper(Tfunc &&func, Targs &&... args) {
        std::forward<Tfunc>(func)(std::forward<Targs>(args)...);
    }

    void value() {}
};

template <class Tfunc, class Tbefore, class Tafter>
auto decorate(Tfunc &&func, Tbefore &&before, Tafter &&after) {
    return [

        func = std::forward<Tfunc>(func),
        before = std::forward<Tbefore>(before),
        after = std::forward<Tafter>(after)

    ] (auto &&... args) -> decltype(auto) {

        before(std::forward<decltype(args)>(args)...);
        RetWrapper<std::result_of_t<Tfunc(decltype(args)...)>> ret(
            func, std::forward<decltype(args)>(args)...
        );
        after(std::forward<decltype(args)>(args)...);

        return ret.value();
    };
}

/*
 * Tests
 */

float test1(float a, float b) {
    std::cout << "Inside test1\n";
    return a * b;
}

void test2() {
    std::cout << "Inside test2\n";
}

int i = 0;

int &test3() {
    return i;
}

int main() {

    auto test1Deco = decorate(
        test1,
        [] (float a, float b) {
            std::cout << "Calling test1 with " << a << " and " << b << '\n';
        },
        [] (float a, float b) {
            std::cout << "Called test1 with " << a << " and " << b << '\n';
        }
    );

    float c = test1Deco(3.5f, 5.1f);

    std::cout << "Yields " << c << '\n';

    auto test2Deco = decorate(
        test2,
        [] () {
            std::cout << "Calling test2\n";
        },
        [] () {
            std::cout << "Called test2\n";
        }
    );

    test2Deco();

    auto test3Deco = decorate(
        test3,
        [] () {
            std::cout << "Calling test3\n";
        },
        [] () {
            std::cout << "Called test3\n";
        }
    );

    auto &i2 = test3Deco();
    i2 = 42;

    std::cout << "Global i = " << i << '\n';

    return 0;
}

[注意:在首次发布后几个小时编辑]

这也许不是OP想要的,但它仍然是相关的,希望对其他寻找答案的人有用

假设有两个函数的签名略有不同:

void foo1(int& x){ cout << "foo1(" << x << ")\n";}
void foo2(double& x){ cout << "foo2(" << x << ")\n";}
使用我在这里给出的示例
main
,叮当声将整个事情内联起来,这是一个好迹象,但并不完全是我们想要检查的。如果您将示例变得更复杂一些(),您可以看到它确实在每个包装器中内联了所有内容,即
foo1
foo2
不以独立形式存在,只以包装形式存在

最初,除了
wrapped
模板之外,我还使用了lambda(利用没有捕获的lambda可以转换为函数指针这一事实),但后来我意识到在这种情况下额外的包装是多余的

这个方法应该适用于传递运行时已知的任何内容,甚至可能包括指向可变全局的指针(尽管这会变得非常混乱)。

\include
#包括
使用名称空间std;
模板
类CClassGenerique
{
typedef TResult(*取消功能)(TParams);
公众:
CClassGenerique(非函数f){m_函数=f;}
void运算符()(t图t){m_函数(t);}
私人:
非函数m_函数;
};
模板
t结果基本功能(TPAP)
{
t=0;

std::cout只需使用完整的模板,而不使用std::function。问题是我想修饰一个绑定方法。这意味着我还必须存储传递给函数的参数,以便在以后调用函数时使用它们。模板与绑定方法一起工作,你可以传递任何可能的()ed.是的,当函数有多个参数时,客户端代码中将使用std::bind来生成可调用的。谢谢。这个答案并没有解决当修饰函数有参数时的情况。我知道,这是它所要求的。如果您需要参数,您只需将运算符()也设置为模板:
templatevoid操作符()(Args&&…Args){m_func(std::forward(Args)…;}
。然后,您还可以处理m_func返回某些内容的情况,使该内容任意复杂。为了记录在案,我认为Quentin的答案更好,应该标记为Quentin的答案,而不是我的答案。但是,我认为应该使用我的解决方案,除非需要Quentin的解决方案,因为它更重要。为什么使用
std::move
事实上,at非常好:)我标记了另一个答案,因为我只需要前面提到的简单行为,而另一个解决方案更简单:)你的代码是C++14。我不知道它是否已经正式标准化,但我不会将其用于生产。@GiulioFranco C++14从去年8月开始正式上线。Clang已经开始了实现了它,GCC 5将很快发布。@Quentin C++14不仅最终确定,而且正式成为一个标准(从1月份开始);它在clang 3.5中得到支持,在GCC 5.0中几乎完全实现。也就是说,应该可以将其移植到C++11(可能限制为一元和二元函数)@PatrykObara我不想尝试:你能添加一个简短的描述吗?
void foo1(int& x){ cout << "foo1(" << x << ")\n";}
void foo2(double& x){ cout << "foo2(" << x << ")\n";}
template<typename Q, void (*foo_p)(Q&)>
void wrapped(int x){
  Q v = 42.2 + x;
  foo_p(v);  
}

int main(){
   using foo_t = void (*)(int); // we coerce foo1 and foo2 into this type 

   foo_t k_int = wrapped<int, foo1>;
   foo_t k_double = wrapped<double, foo2>;

   k_int(-1); //cout: foo1(41)
   k_double(-1); //cout: foo2(41.2)   
   return 0;
}
    #include  <iostream>
    #include <string>
    using namespace std;

    template <typename TResult, typename TParams>
    class CClassGenerique
    {
        typedef TResult (*uneFonction) (TParams);
    public :
        CClassGenerique (uneFonction f){ m_function = f; }
        void operator () (TParams t)    {  m_function (t); }
private :    
        uneFonction m_function;
    };

    template <typename TResult, typename TParams>
    TResult BasicFunction (TParams p)
    {
        TResult t=0;
        std::cout<<" Value = " << p <<endl;
        return t;
    }

    int main (int argc, char* argv[])
    {

        CClassGenerique<int, int>       c1 (BasicFunction<int, int>);
        CClassGenerique<int, char*>     c2 (BasicFunction<int, char*>);
        CClassGenerique<char*, char*>   c3 (BasicFunction<char*, char*>);


        c1(3);
        c2("bonsoir");
        c3("hello");
        return 0;
    }