【问题标题】:Template print function C++模板打印函数 C++
【发布时间】:2018-09-06 14:43:08
【问题描述】:

到目前为止,我写了这个:

template <typename TType>
void print_vector(const std::vector<TType>& vec)
{
    typename  std::vector<TType>::const_iterator it;
    std::cout << "(";
    for(it = vec.begin(); it != vec.end(); it++)
    {
        if(it!= vec.begin()) std::cout << ",";
        std::cout << (*it);
    }
    std::cout << ")";
}

template<>
template <typename T2>
void print_vector(const std::vector< std::vector<T2> >& vec)
{
    for( auto it= vec.begin(); it!= vec.end(); it++)
    {
        print_vector(*it);
    }
}

第一个函数适用于std::vector&lt; double&gt; 等。现在我也希望能够打印std::vector&lt; std::vector&lt; TType&gt;&gt; 的东西。第二部分没有编译,但这是我解决任务的“想法”。关于如何实现这种行为的任何建议?

Compilation Error: too many template-parameter-lists

【问题讨论】:

  • 你不能部分特化一个函数,你需要创建一个新的重载
  • 请注意,您的第二个 print 不会在内部向量周围输出额外的 (, )

标签: c++ templates printing


【解决方案1】:

去掉template&lt;&gt;部分,函数模板重载就可以正常工作了。

template <typename TType>
void print_vector(const std::vector<TType>& vec)
{
    typename  std::vector<TType>::const_iterator it;
    std::cout << "(";
    for(it = vec.begin(); it != vec.end(); it++)
    {
        if(it!= vec.begin()) std::cout << ",";
        std::cout << (*it);
    }
    std::cout << ")";
}

template <typename T2>
void print_vector(const std::vector< std::vector<T2> >& vec)
{
    for( auto it= vec.begin(); it!= vec.end(); it++)
    {
        print_vector(*it);
    }
}

【讨论】:

    【解决方案2】:

    您实际上可能想要为该问题寻求更通用的解决方案,允许打印几乎任何可迭代类型:

    #include <vector>
    #include <iostream>
    
    template <typename Iterable>
    std::ostream& operator<<(std::ostream& os, const Iterable& vals)
    {
        for (const auto& val : vals)
            os << val << std::endl;
        return os;
    }
    
    int main()
    {
        auto simple_vec = std::vector<int>{3, 5 , 7};
        std::cout << simple_vec;
        auto nested_vec = std::vector<std::vector<int>>{{1, 2}, {3, 4}};
        std::cout << nested_vec;
    }
    

    要进一步改进此解决方案,您可以尝试使用 SFINAE,以确保模板化的 &lt;&lt; 仅可用于可迭代类型。

    【讨论】:

    • 你的方法捕获全部。如果没有 SFINAE,我不鼓励这样做。其实我更喜欢OP的版本。
    • 你忘记输出(, )
    • 这就是为什么我最后添加了关于 SFINAE 的部分,因为它默认是攻击性的。
    【解决方案3】:

    如果您让函数打印基本类型并递归地使用自身覆盖向量:

    template<typename T>
    void print( const T &t ) 
    { 
        std::cout << t; 
    }
    
    template<typename T>
    void print( const std::vector<T> &v ) 
    { 
        std::cout << '[';
        for( auto it = v.begin(); it != v.end(); ++it ) {
             if( it != v.begin() ) std::cout << ',';
             print( *it );
        }
        std::cout << ']';
    }
    

    那么你不需要为向量的向量或向量的向量等编写特殊的。

    live example

    【讨论】:

    • OP 的版本应该已经处理向量的向量的向量...但是您的版本将允许向量列表的向量... :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多