我可以避免在模板实例化期间显式写出我的 class-模板参数类型吗?
Can I avoid explicitly writing out my class-template parameter-type during template instantiation?
我写了一个模板化的 RAII-class,叫做 SaveGuard
,它的构造函数复制了指定对象的当前状态,然后析构函数从保存的状态恢复对象.这样我就可以对对象进行临时更改,并且我保证它们将在当前范围结束时自动恢复(参见下面的代码)。
一切正常;我的问题是:有没有一种方法可以避免每次声明 SaveGuard
时都必须显式输入要保存的对象的类型?即而不是输入:
const SaveGuard<std::string> guard(myStr);
我更喜欢这样输入:
const SaveGuard<> guard(myStr);
由于对象的类型可能相当复杂,而且我可能会在很多地方为它声明 SaveGuard
个对象,如果可以的话,它会节省大量的输入并整理我的代码。
但是,尝试这样做会产生此错误:
temp.cpp:23:17: error: too few template arguments for class template 'SaveGuard'
const SaveGuard<> guard(myStr);
代码如下:
#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;
}
当运行时,代码打印出来:
At point A, myStr=foo
At point B, myStr=foobar
At point C, myStr=foo
在 C++17 中,您可以使用 class 模板参数推导。这要求您完全省略模板参数列表:
SaveGuard guard(myStr); // OK - deduces T as std::string
在 C++17 之前,无法推导 class 模板参数,因此必须使用辅助函数来代替(std::make_pair
就是一个例子)。您可以编写一个 MakeSaveGuard
函数,从函数参数类型推导出模板参数(这需要 SaveGuard
才能正确移动)。
我写了一个模板化的 RAII-class,叫做 SaveGuard
,它的构造函数复制了指定对象的当前状态,然后析构函数从保存的状态恢复对象.这样我就可以对对象进行临时更改,并且我保证它们将在当前范围结束时自动恢复(参见下面的代码)。
一切正常;我的问题是:有没有一种方法可以避免每次声明 SaveGuard
时都必须显式输入要保存的对象的类型?即而不是输入:
const SaveGuard<std::string> guard(myStr);
我更喜欢这样输入:
const SaveGuard<> guard(myStr);
由于对象的类型可能相当复杂,而且我可能会在很多地方为它声明 SaveGuard
个对象,如果可以的话,它会节省大量的输入并整理我的代码。
但是,尝试这样做会产生此错误:
temp.cpp:23:17: error: too few template arguments for class template 'SaveGuard'
const SaveGuard<> guard(myStr);
代码如下:
#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;
}
当运行时,代码打印出来:
At point A, myStr=foo
At point B, myStr=foobar
At point C, myStr=foo
在 C++17 中,您可以使用 class 模板参数推导。这要求您完全省略模板参数列表:
SaveGuard guard(myStr); // OK - deduces T as std::string
在 C++17 之前,无法推导 class 模板参数,因此必须使用辅助函数来代替(std::make_pair
就是一个例子)。您可以编写一个 MakeSaveGuard
函数,从函数参数类型推导出模板参数(这需要 SaveGuard
才能正确移动)。