这是我经常遇到的RAII问题。我想知道是否有人对此有一个好的解决方案。
从您的标准RAII实用程序类开始:
class RAIIHelper {
RAIIHelper() {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
现在,由于各种原因,我需要将其作为模板。我们还假设其构造函数采用模板参数类型的参数:
template <typename T>
class RAIIHelper {
RAIIHelper(T arg) {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
现在考虑一个使用站点:
void func() {
RAIIHelper<SomeType> helper(someObj);
}
当可以从
SomeType
推导出someObj
时,不得不将其写出来很烦人,因此我编写了一个辅助函数来推断类型:template <typename T>
RAIIHelper<T> makeRAIIHelper(T arg) {
return RAIIHelper<T>(arg);
}
现在,我可以像这样使用它:
void func() {
auto helper = makeRAIIHelper(someObj);
}
太好了吧?除非有一个障碍:现在要求
RAIIHelper
是可复制或可移动的,并且释放资源的析构函数可以被调用两次:一次是makeRAIIHelper
返回的临时变量,一次是调用函数中的局部变量。实际上,我的编译器执行RVO,而析构函数仅被调用一次。但是,这不能保证。从以下事实可以看出这一点:如果我尝试给
RAIIHelper
一个= delete
'd move构造函数,则该代码将不再编译。我可以向RAIIHelper添加其他状态,以便它知道从其移出后不调用
ReleaseTheResource()
,但是在我添加makeRAIIHelper()
以获得类型推论之前,这是不必要的额外工作。有没有一种方法可以获取类型推断,而不必在
RAIIHelper
中添加额外的状态? 最佳答案
有一个非常简单的解决方案:使用对临时对象的引用,而不是将其复制到局部变量中。
void func()
{
auto&& helper = makeRAIIHelper(someObj);
}
关于c++ - RAII和推导的模板参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24743328/