Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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++ ScopedExit实现:将参数传递给函数对象_C++_C++11_Function Pointers - Fatal编程技术网

C++ ScopedExit实现:将参数传递给函数对象

C++ ScopedExit实现:将参数传递给函数对象,c++,c++11,function-pointers,C++,C++11,Function Pointers,我正在尝试实现简单的ScopedExit类。代码如下: #include <iostream> #include <functional> template<class R, class... Args> class ScopedExit { public: ScopedExit(std::function<R(Args...)> exitFunction) { exitFunc_ = exitFunction;

我正在尝试实现简单的ScopedExit类。代码如下:

#include <iostream>
#include <functional>

template<class R, class... Args>
class ScopedExit
{
public:
    ScopedExit(std::function<R(Args...)> exitFunction)
    {
        exitFunc_ = exitFunction; 
    }

    ~ScopedExit()
    {
        exitFunc_();
    }
private:
    std::function<R(Args...)> exitFunc_;
};

template<>
class ScopedExit<void>
{
public:
    ScopedExit(std::function<void ()> exitFunction)
    {
        exitFunc_ = exitFunction; 
    }

    ~ScopedExit()
    {
        exitFunc_();
    }
private:
    std::function<void ()> exitFunc_;
};

void foo()
{
    std::cout << "foo() called\n";
}

class Bar
{
public:
    void BarExitFunc(int x, int y)
    {
        std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
    }
};

int main()
{
    Bar b;
    std::cout << "Register scoped exit func\n";
    {
        ScopedExit<void, int, int> exitGuardInner(std::bind(&Bar::BarExitFunc, &b, 18, 11));
    }
    ScopedExit exitGuardOutter(foo);
    std::cout << "About to exit from the scope\n";
    return 0;
}
#包括
#包括
模板
类ScopedExit
{
公众:
ScopedExit(std::function exitFunction)
{
exitFunc=exitFunction;
}
~ScopedExit()
{
exitFunc_u2;();
}
私人:
std::函数exitFunc\ux;
};
模板
类ScopedExit
{
公众:
ScopedExit(std::function exitFunction)
{
exitFunc=exitFunction;
}
~ScopedExit()
{
exitFunc_u2;();
}
私人:
std::函数exitFunc\ux;
};
void foo()
{
std::cout1)例如,您可以将参数保存在
tuple
中。但是,在您的情况下,您可以简单地调用
exitFunc()
,函数定义应该是
std::function exitFunction
,因为您已经将参数绑定到函数。可能是这样的

#include <iostream>
#include <functional>
#include <tuple>

template<size_t...>
struct indices {};
template<size_t N, size_t... Is>
struct gen_indices : gen_indices<N - 1, N - 1, Is...>
{
};
template<size_t... Is>
struct gen_indices<0, Is...> : indices<Is...>
{
};

template<class R, class... Args>
class ScopedExit
{
public:
    ScopedExit(std::function<R(Args...)> exitFunction, Args&&... args)
    : arguments_(std::forward_as_tuple(args...))
    {
        exitFunc_ = exitFunction;
    }

    ~ScopedExit()
    {
       call(gen_indices<sizeof...(Args)>());
    }
private:
    template<size_t... Idx>
    void call(indices<Idx...>)
    {
       exitFunc_(std::forward<Args>(std::get<Idx>(arguments_))...);
    }
    std::tuple<Args...> arguments_;
    std::function<R(Args...)> exitFunc_;
};

template<>
class ScopedExit<void>
{
public:
    ScopedExit(std::function<void ()> exitFunction)
    {
        exitFunc_ = exitFunction; 
    }

    ~ScopedExit()
    {
        exitFunc_();
    }
private:
    std::function<void ()> exitFunc_;
};

void foo()
{
    std::cout << "foo() called\n";
}

class Bar
{
public:
    void BarExitFunc(int x, int y)
    {
        std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
    }
};

int main()
{
    Bar b;
    std::cout << "Register scoped exit func\n";
    {
        ScopedExit<void, int, int> exitGuardInner
        (
           std::bind(&Bar::BarExitFunc, &b, std::placeholders::_1, 
           std::placeholders::_2), 10, 18
        );
    }
    ScopedExit<void> exitGuardOutter(foo);
    std::cout << "About to exit from the scope\n";
    return 0;
}
#包括
#包括
#包括
模板
结构索引{};
模板
结构gen_索引:gen_索引
{
};
模板
结构gen_索引:索引
{
};
模板
类ScopedExit
{
公众:
ScopedExit(std::function exitFunction,Args&&…Args)
:参数(std::转发作为元组(args…)
{
exitFunc=exitFunction;
}
~ScopedExit()
{
调用(gen_index());
}
私人:
模板
作废通知(索引)
{
exitFunc(std::forward(std::get(arguments))…);
}
std::元组参数;
std::函数exitFunc\ux;
};
模板
类ScopedExit
{
公众:
ScopedExit(std::function exitFunction)
{
exitFunc=exitFunction;
}
~ScopedExit()
{
exitFunc_u2;();
}
私人:
std::函数exitFunc\ux;
};
void foo()
{
标准::cout
如何将exit的函数参数传递给它?例如,我使用两个整数参数绑定BarExitFunc:18和11。那么如何将其传递给析构函数中的exitFunc_uu2;呢

我看不出有任何理由在析构函数中调用时将参数传递给
exitFunc.
。无论您做什么,您都必须在
ScopedExit
构造函数中预先提供这些参数

最简单的方法是在定义站点使用
函数
绑定
任何必需的参数,就像您已经在做的那样:

ScopedExit<R> guard(std::bind(someFunction, someArg, otherArg));
真的,我不明白这一点,因为它使模板更加复杂,但为什么不…只需在构造函数本身中绑定/转发参数,并仍然存储一个
函数

请注意,您原来的可变模板类现在已成为一个灵活的非模板类,只有一个模板构造函数,它的模板参数是自动推导的,并且它几乎可以接受您可以想到的任何类型的函子


注意:我说的几乎是任何函子,因为这不适用于默认参数:

void foobar(int = 0) {}
ScopedExit guard5(foobar); // error: too few arguments to function
即使您直接存储了一个
Functor
而不是
std::function
,您也无法使用默认参数(即使有默认参数,
foobar
的签名仍然是
void(int)
)因此,我们必须在定义站点处理这种情况,例如:

void foobar(int = 0) {}
ScopedExit guard5([]() { foobar(); });
class ScopedExit
{
public:
    template<typename Functor>
    ScopedExit(Functor exitFunction)
    {
        exitFunc_ = exitFunction; 
    }

    ~ScopedExit()
    {
        exitFunc_();
    }
private:
    std::function<void()> exitFunc_;
};

int foo() { return 0; }

struct Bar {
  void bye(int, int) {}
};

struct Baz {
  void operator ()() {}
};

int main() {
    const std::string what = "lambda!";
    ScopedExit guard1([&]() { std::cout << "yay a " << what << std::endl; });

    ScopedExit guard2(foo); // note how std::function<void()> accepts non-void return types

    Bar b;
    ScopedExit guard3(std::bind(&Bar::bye, &b, 1, 2));

    ScopedExit guard4(Baz());
}
void foobar(int = 0) {}
ScopedExit guard5(foobar); // error: too few arguments to function
void foobar(int = 0) {}
ScopedExit guard5([]() { foobar(); });