【问题标题】:Can I avoid explicitly writing out my class-template parameter-type during template instantiation?我可以避免在模板实例化期间明确写出我的类模板参数类型吗?
【发布时间】:2020-11-03 01:04:35
【问题描述】:

我编写了一个名为SaveGuard 的小模板化RAII 类,它的构造函数复制指定对象的当前状态,然后析构函数从该保存状态恢复对象。这样我就可以对对象进行临时更改,并保证它们将在当前范围结束时自动恢复(请参见下面的代码)。

一切正常;我的问题是:有没有办法让我避免每次声明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++ templates template-argument-deduction


    【解决方案1】:

    在 C++17 中,您可以使用类模板参数推导。这要求您完全省略模板参数列表:

    SaveGuard guard(myStr);  // OK - deduces T as std::string
    

    在 C++17 之前,无法推断类模板参数,因此必须使用辅助函数(std::make_pair 就是一个例子)。您可以编写一个 MakeSaveGuard 函数,从函数参数类型推导出模板参数(这要求 SaveGuard 可以正确移动)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-26
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多