HC4*_*ica 8 c++ templates raii c++11
这是我经常遇到的RAII问题.我想知道是否有人有一个很好的解决方案.
从标准RAII实用程序类开始:
class RAIIHelper {
RAIIHelper() {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
Run Code Online (Sandbox Code Playgroud)
现在,由于各种原因,我需要将其作为模板.我们还说它的构造函数接受模板参数类型的参数:
template <typename T>
class RAIIHelper {
RAIIHelper(T arg) {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
Run Code Online (Sandbox Code Playgroud)
现在考虑使用网站:
void func() {
RAIIHelper<SomeType> helper(someObj);
}
Run Code Online (Sandbox Code Playgroud)
SomeType
当它可以从中推断时必须写出来很烦人someObj
,因此我编写了一个辅助函数来推断出类型:
template <typename T>
RAIIHelper<T> makeRAIIHelper(T arg) {
return RAIIHelper<T>(arg);
}
Run Code Online (Sandbox Code Playgroud)
现在我可以像这样使用它:
void func() {
auto helper = makeRAIIHelper(someObj);
}
Run Code Online (Sandbox Code Playgroud)
很棒,对吧?除了有一个障碍:RAIIHelper
现在需要是可复制的或可移动的,并且释放资源的析构函数可能被调用两次:一次用于返回的临时值makeRAIIHelper
,一次用于调用函数中的局部变量.
实际上,我的编译器执行RVO,并且只调用析构函数一次.但是,这不能保证.这可以从以下事实看出:如果我尝试给出RAIIHelper
一个= delete
'd move构造函数,代码就不再编译了.
我可以向RAIIHelper添加额外的状态,以便它知道ReleaseTheResource()
在移动之后不会调用,但这是额外的工作,在我添加makeRAIIHelper()
以获得类型扣除之前是不必要的.
有没有办法可以获得类型演绎,而无需添加额外的状态RAIIHelper
?
有一个非常简单的解决方案:使用对临时对象的引用,而不是将其复制到局部变量中.
void func()
{
auto&& helper = makeRAIIHelper(someObj);
}
Run Code Online (Sandbox Code Playgroud)