1

我想创建一个模板函数,该函数生成具有name()方法的事物数组的字符串表示形式。这些东西可以按价值保存,也可以按引用保存(原始或智能)

        template< typename T>
        struct GetStringRepresentation;

        template< typename T>
        struct GetStringRepresentation< std::vector< std::unique_ptr< T > > >
        {
            inline void ()( const std::vector< std::unique_ptr< T > >& seq, std::string& out )
            {
                size_t size = seq.size();
                for (int i=0; i< size; i++)
                {
                    if (i > 0)
                        out += ", ";
                    out += seq[i]->name();
                }
            }
        };

       template< typename T>
        struct GetStringRepresentation< std::vector< std::shared_ptr< T > > >
        {
            inline void ()( const std::vector< std::shared_ptr< T > >& seq, std::string& out )
            {
                size_t size = seq.size();
                for (int i=0; i< size; i++)
                {
                    if (i > 0)
                        out += ", ";
                    out += seq[i]->name();
                }
            }
        };

        template< typename T>
        struct GetStringRepresentation< std::vector< T* > >
        {
            inline void ()( const std::vector< T* >& seq, std::string& out )
            {
                size_t size = seq.size();
                for (int i=0; i< size; i++)
                {
                    if (i > 0)
                        out += ", ";
                    out += seq[i]->name();
                }
            }
        };

        template< typename T>
        struct GetStringRepresentation< std::vector< T > >
        {
            inline void ()( const std::vector< T >& seq, std::string& out )
            {
                size_t size = seq.size();
                for (int i=0; i< size; i++)
                {
                    if (i > 0)
                        out += ", ";
                    out += seq[i].name();
                }
            }
        };

正如您可以清楚地看到的那样,有很多重复,特别是在参考专业之间。我不太了解执行此操作的最佳方法,我希望看到一种更好的方法来删除部分或全部代码重复

4

2 回答 2

4

这是一个帮助您入门的提示:仅专门化打印方法:

template <typename T> void print(T const & x)
{
    std::cout << printer<T>::print(x) << std::endl;
}

template <typename T> struct printer
{
    static std::string print(T const & x) { return x.name(); }
};
template <typename U> struct printer<U*>
{
    static std::string print(U * p) { return p->name(); }
};

这样你只需要编写一次循环,打印机会处理细节。您甚至可以进一步抽象它并制作一种is_pointer_like特征(所有支持的东西->),然后您专门针对所有智能指针:

printer<T, is_pointer_like<T>::value>::print(x); // etc.

template <typename T, bool> struct printer { /* as before */ }

template <typename T> struct printer<T, true>
{
    static std::string print(T const & p) { return p->name(); }
};

// Traits:
template <typename T> struct is_pointer_like : std::false_type { };
template <typename U> struct is_pointer_like<U*> : std::true_type { };
template <typename U> struct is_pointer_like<std::shared_ptr<U>> : std::true_type { };

对于类似的想法,请参阅漂亮的打印机

于 2012-04-14T16:32:09.153 回答
1

我会这样写:

struct GetStringRepresentation
{
     template<typename T>
     std::string operator()(std::vector<T> const & seq)
     {
        std::string out;
        size_t size = seq.size();
        for (size_t i=0; i< size; i++)
        {
           if (i > 0)
              out += ", ";
           out += get(seq[i]); //call get() to get the string
        }
        return out;
     }

private:

     template<typename T>
     std::string const & get(T const & t) { return t.name; }

     template<typename T>
     std::string const & get(T const * t) { return t->name; }

     template<typename T>
     std::string const & get(std::unique_ptr<T> const & t) { return t->name; }

     template<typename T>
     std::string const & get(std::shared_ptr<T> const & t) { return t->name; }
};
于 2012-04-14T16:38:40.467 回答