Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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++ 什么';s是C+中的最短路径+;11(或更新版本)创建RAII包装而不必编写新类?_C++_C++11_C++14_C++17_Raii - Fatal编程技术网

C++ 什么';s是C+中的最短路径+;11(或更新版本)创建RAII包装而不必编写新类?

C++ 什么';s是C+中的最短路径+;11(或更新版本)创建RAII包装而不必编写新类?,c++,c++11,c++14,c++17,raii,C++,C++11,C++14,C++17,Raii,通常情况下,我需要一个简单的RAII包装器,但由于时间限制和组织问题等原因,我不想为此创建一个全新的类。我的quick-n-dirty解决方案如下 假设我希望确保在作用域结束时,布尔值切换回其原始状态: bool prevState = currState; currState = newState; std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevSta

通常情况下,我需要一个简单的RAII包装器,但由于时间限制和组织问题等原因,我不想为此创建一个全新的类。我的quick-n-dirty解决方案如下

假设我希望确保在作用域结束时,布尔值切换回其原始状态:

bool prevState = currState;
currState      = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
    currState = prevState;
    delete p;
});
bool prevState=currState;
currState=newState;
std::unique_ptr txEnder(新int(0),[&prevState](int*p){
currState=prevState;
删除p;
});
此解决方案工作正常,但脏的部分是分配和取消分配该整数的必要性,以便使
唯一\u ptr
工作并在销毁时调用自定义析构函数

有没有一种更干净的方法可以做到这一点,而不必编写整个类,并为虚拟
int
摆脱
new

您可以使用


比您的要好一点:您可以在自定义析构函数中使用
&prevState
,而无需删除它,因此您无需
新建
删除
某些内容:

void foo(bool & currState, bool newState)
{
    bool prevState = currState;
    currState      = newState;
    std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
        currState = prevState;
    });
    cout << "currState: " << currState << endl;
}
void foo(bool&currState,bool newState)
{
布尔状态=当前状态;
currState=newState;
std::unique_ptr txEnder(&prevState,[&prevState,&currState](bool*p){
currState=prevState;
});

不能不要使用
std::function
。它会创建很多代码,包括vtables。
如果您绝对不想使用任何外部类或函数,请执行以下操作:

bool foo_2() {
    bool f = false;
    auto eos = [&](void*){
        f = true;
    };
    std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
    return f;
}

怎么样
gsl::finally
?库没有boost那么重,而且
finally
不使用
std::function
,因此可以轻松地内联。也没有动态分配
std::unique\u ptr

using namespace std;

void foo(bool & currState, bool newState)
{
    auto revertState = gsl::finally([prevState = currState, &currState]{
        currState = prevState;
    });
    currState = newState;       
    cout << "currState: " << currState << endl;
}


int main() {
    bool state = false;
    foo(state, true);
    cout << "state: " << state << endl;
    return 0;
}
使用名称空间std;
void foo(布尔和柯尔斯塔、布尔新闻州)
{
自动还原状态=gsl::最终([prevState=currState,&currState]{
currState=prevState;
});
currState=newState;

你不能确定你需要分配什么吗?写一个简单的类,在构造时给它一个lambda,然后在析构函数中调用它怎么样?类似于锁守卫。@QuantumPhysica学家我说的不是新类(@πάντα)ῥεῖ 我知道,伙计。我以前在Stackoverflow上讨论过一个(我称之为SmartHandle).但是,再一次,我没有自由在我工作的所有项目中这样做,这取决于许多情况,从匆忙到项目组织问题。@QuantumPhysician如果你因为这样愚蠢的情况而不能做必要的工作,那该有多可惜。但我知道这种情况。这是完美的。我不知道如何做到这一点我没有想到。我只是有点偏执,认为这是否违反了任何规则!这是一个有趣的问题解决方案。我只想指出,这个解决方案可能不是最有效的,因为
std::function
应用类型擦除,这意味着动态内存分配(可能是小缓冲区优化)和虚拟函数开销(例如,请参阅)“经典”范围保护,例如来自Boost的范围保护,可能更有效。@量子物理学家还注意到,有人建议添加范围保护(
std::scope\…
)进入Stadndard库:。@DanielLangr如果他们在lamdas中添加析构函数,我会更加感激……这将是一个杀手级功能!耶。Boost.:-/你的解决方案可能是正确的,但挑战是要有最短的路径。被接受的答案是超短的,没有任何动态分配。
template<class F>
auto call_at_end_of_scope(F&& f){
    auto eos = [f{std::forward<F>(f)}](void*){f();};
    return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}

bool foo_3() {
    bool f = false;
    auto handle = call_at_end_of_scope([&](){
        f = true;
    });
    return f;
}
using namespace std;

void foo(bool & currState, bool newState)
{
    auto revertState = gsl::finally([prevState = currState, &currState]{
        currState = prevState;
    });
    currState = newState;       
    cout << "currState: " << currState << endl;
}


int main() {
    bool state = false;
    foo(state, true);
    cout << "state: " << state << endl;
    return 0;
}