[英]Can I avoid explicitly writing out my class-template parameter-type during template instantiation?
I wrote a little templated RAII-class called SaveGuard
whose constructor makes a copy of the current state of a specified object, and then later on the destructor restores the object from that saved state.我写了一个名为SaveGuard
的模板化 RAII 类,它的构造函数复制指定对象的当前状态,然后析构函数从该保存状态恢复对象。 That way I can make temporary changes to an object and I am guaranteed that they will be auto-reverted at the end of the current scope (see code below).这样我就可以对一个对象进行临时更改,并且我保证它们将在当前范围的末尾自动恢复(参见下面的代码)。
That all works fine;一切正常; my question is this: Is there a way for me to avoid having to explicitly type out the type of the to-be-saved object every time I declare a SaveGuard
?我的问题是:有没有办法让我避免每次声明SaveGuard
都必须明确输入要保存的对象的SaveGuard
? ie rather than typing this:即而不是输入这个:
const SaveGuard<std::string> guard(myStr);
I'd prefer to type something like this:我更喜欢输入这样的内容:
const SaveGuard<> guard(myStr);
Since the type of the object might be rather elaborate, and I might be declaring SaveGuard
objects for it in many places, it would save a lot of typing and declutter my code if I could.由于对象的类型可能相当复杂,而且我可能会在很多地方为它声明SaveGuard
对象,如果可以的话,它会节省大量的输入并整理我的代码。
However, trying that yields this error:但是,尝试会产生此错误:
temp.cpp:23:17: error: too few template arguments for class template 'SaveGuard'
const SaveGuard<> guard(myStr);
Code follows:代码如下:
#include <iostream>
#include <string>
/** Convenience class to place on the stack for RAII-swapping of a table out to temporary storage and then back again in the destructor */
template<class T> class SaveGuard
{
public:
SaveGuard(T & saveMe) : _saveMe(saveMe), _tempHolder(saveMe) {/* empty */} // save the current value
~SaveGuard() {_saveMe = _tempHolder;} // restore the saved value
private:
T & _saveMe;
T _tempHolder;
};
int main(int argc, char ** argv)
{
std::string myStr = "foo";
std::cout << "At point A, myStr=" << myStr << std::endl;
{
const SaveGuard<std::string> guard(myStr);
// Make some temporary modifications to myStr
myStr += "bar";
std::cout << "At point B, myStr=" << myStr << std::endl;
}
std::cout << "At point C, myStr=" << myStr << std::endl;
return 0;
}
When run, the code print out this:运行时,代码打印出:
At point A, myStr=foo
At point B, myStr=foobar
At point C, myStr=foo
In C++17, you can use class template argument deduction.在 C++17 中,您可以使用类模板参数推导。 This requires you to completely omit the template argument list:这要求您完全省略模板参数列表:
SaveGuard guard(myStr); // OK - deduces T as std::string
Before C++17, class template arguments cannot be deduced, so a helper function had to be used instead ( std::make_pair
is an example of this).在 C++17 之前,不能推导出类模板参数,因此必须使用辅助函数( std::make_pair
就是一个例子)。 You could write a MakeSaveGuard
function that deduces the template argument from the function argument type (this requires SaveGuard
to be properly movable).您可以编写一个MakeSaveGuard
函数,从函数参数类型推导出模板参数(这要求SaveGuard
可以正确移动)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.