【问题标题】:How to specify template function for STL container?如何为 STL 容器指定模板函数?
【发布时间】:2016-08-11 05:38:05
【问题描述】:

我需要将不同类型的值写入std::wstringstream。有一次我们需要写入一个或多个值。我试图像这样实现它:

wstringstream _str;     

template<typename ValueType> //(1)
void WriteValue(const ValueType& val)
{
    _str << val;
}

template<typename ValueType> //(2)
void WriteValue(const std::vector<ValueType>& vals)
{
    for (auto it = vals.begin(); it!= vals.end(); ++it)
    {
        WriteValue<ValueType>(*it);
        _str << L" ";            
    }
}

template<typename ValueType>
void WriteRecord(const std::wstring& name, const ValueType & val)
{
     _str << name;
     WriteValue<ValueType>(val);
}

void Foo()
{
    int bar = 0;
    WriteRecord<int>(L"Lorem", bar); //it's okay

    std::vector<int> buz(4, 0);
    WriteRecord<int>(L"ipsum", buz); //it's error
}

我收到以下错误:

"cannot convert argument 2 from 'std::vector< int, std::allocator < int > >' 
to 'int &'". As seen compiler tries to pass a vector to (1), not (2).

为什么会这样?是否可以让它选择(2)专门的功能模板?

【问题讨论】:

    标签: c++ templates stl


    【解决方案1】:
    WriteRecord<int>(L"ipsum", buz);
               ^^^^^
    

    您在这里明确地说ValueType 应该是int。所以函数签名是:

    void WriteRecord(const std::wstring& name, const int& val)
    

    当您尝试将std::vector 作为第二个参数传递时,编译器无法将std::vector 转换为int

    对于函数,很少需要显式命名模板参数的类型,您可以这样编写调用:

    WriteRecord(L"ipsum", buz); //Compiler deduces ValueType
    

    如果确实需要指定模板参数,请使用decltype

    WriteRecord<decltype(buz)>(L"ipsum", buz);
    

    或者直接写出来(不推荐)

    WriteRecord<std::vector<int>>(L"ipsum", buz);
    

    【讨论】:

      【解决方案2】:
      std::vector<int> buz(4, 0);
      WriteRecord<int>(L"ipsum", buz);
      //          ^^^
      

      您告诉编译器 ValueTypeint 但随后您将 vector&lt;int&gt; 作为参数传递。编译器完全有能力推导出模板参数类型,所以不要在任何地方不必要地指定它们。您的 Foo 函数应如下所示:

      void Foo()
      {
          int bar = 0;
          WriteRecord(L"Lorem", bar);
      
          std::vector<int> buz(4, 0);
          WriteRecord(L"ipsum", buz);
      }
      

      同样,删除在其他函数中对WriteValue 的调用中显式指定的模板参数。

      【讨论】:

        猜你喜欢
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 2013-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多