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

时间:2015-03-19 20:22:42

标签: c++ templates c++11 c++14

我有以下代码,问题是当我尝试将basic_string类型传递给writeContainer函数时,它给出了错误,它将类型Cont读为 std :: _ St​​ring_val< std :: _ Simple_types> 所以它给了我像没有size()方法的错误,并且没有for循环的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

1 个答案:

答案 0 :(得分:2)

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

你的例子中发生了什么。在这个特定的实现中,std::basic_string派生自一个名为_String_val的内部类,由于不幸的巧合,恰好是一个单参数模板。因此Cont被推断为_String_val,但实例化失败,因为_String_val没有名为size的方法(该方法由basic_string本身实现)。

尽管您声称相反,但在使用std::vector代替std::basic_string时,我得到了similar error - 出于同样的原因。

现在,没有理由让Cont成为模板模板参数(并且有充分的理由不 - 它不起作用)。使它成为普通类型参数,或者让函数接受一对迭代器。这些方面的东西:

template<typename Cont>
void writeContainer(Stream& stream, const Cont& outValue);

// or

template<typename Iter>
void writeRange(Stream& stream, Iter first, Iter last);