如何为STL容器指定模板函数

How to specify template function for STL container?

本文关键字:函数 STL      更新时间:2023-10-16

我需要将不同类型的值写入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(专门的功能模板?

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);
std::vector<int> buz(4, 0);
WriteRecord<int>(L"ipsum", buz);
//          ^^^

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

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

类似地,删除其他函数中对WriteValue的调用中明确指定的模板参数。