C++将模板类型作为参数传递会出错

C++ passing template type as argument gives error

本文关键字:参数传递 出错 类型 C++      更新时间:2023-10-16

我有以下代码,问题是当我尝试将basic_string类型传递给 writeContainer 函数时,它给了我错误,它将 Cont 类型读取为 std::_String_val<std::_Simple_types> 所以它给了我错误,就像没有 size(( 方法一样,并且每个循环都没有 end(( 或 begin(( 方法。

好消息是,当我使用矢量时,它工作正常,即使它们是相同的概念! 任何帮助表示赞赏

template< template<typename> class Cont, typename T >
void writeContainer(Stream& stream, const Cont<T>& outValue) {
    stream << (int32_t)outValue.size(); 
    for (auto& v : outValue) {
        stream << v;
    }
}
template<typename T> 
Stream& operator<<(Stream& stream, const basic_string<T>& outValue) {
    writeContainer(stream, outValue); 
    return stream; 
}

得到的错误,我使用 VS2013

error C2039: 'size' : is not a member of 'std::_String_val<std::_Simple_types<char>>'
see reference to function template instantiation 'void  writeContainer<std::_String_val,std::_Simple_types<char>>(Stream &,const std::_String_val<std::_Simple_types<char>> &)' being compiled
see reference to function template instantiation 'Stream &operator <<<char>(Stream &,const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)' being compiled
error C3312: no callable 'begin' function found for type 'const std::_String_val<std::_Simple_types<char>>'
error C3312: no callable 'end' function found for type 'const std::_String_val<std::_Simple_types<char>>'
error C2065: 'v' : undeclared identifier

对于模板模板参数,参数必须是具有完全相同参数数的类模板 - 计算具有默认值的参数。因此,即使std::vector可以用一个参数实例化,它也是一个双参数模板(第二个参数具有默认值(,并且不能是Cont的参数。同样,std::basic_string是一个三参数模板。

在你的例子中发生的事情是这样的。在这个特定的实现中,std::basic_string派生自一个名为 _String_val 的内部类,不幸的是,它恰好是一个单参数模板。所以Cont被推导出为_String_val,但随后实例化失败,因为_String_val没有一个名为size的方法(该方法由basic_string本身实现(。

尽管您声称相反,但我在使用std::vector代替std::basic_string时遇到了类似的错误 - 出于完全相同的原因。

现在,没有理由将Cont作为模板模板参数(并且有充分的理由不这样做 - 它不起作用(。使其成为普通类型参数,否则让函数采用一对迭代器。大致如下:

template<typename Cont>
void writeContainer(Stream& stream, const Cont& outValue);
// or
template<typename Iter>
void writeRange(Stream& stream, Iter first, Iter last);