【问题标题】:typedefs for templated classes?模板类的类型定义?
【发布时间】:2010-09-20 01:38:31
【问题描述】:

是否可以typedef 使用模板的长类型?例如:

template <typename myfloat_t>
class LongClassName
{
    // ...
};

template <typename myfloat_t>
typedef std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > LongCollection;

LongCollection<float> m_foo;

这不起作用,但是有没有办法达到类似的效果?我只是想避免键入和阅读几乎覆盖编辑器窗口整个宽度的类型定义。

【问题讨论】:

    标签: c++ templates typedef


    【解决方案1】:

    不,目前不可能。这将在 C++0X AFAIK 中实现。

    我能想到的最好的是

    template<typename T> struct LongCollection {
        typedef std::vector< boost::shared_ptr< LongClassName<T> > > type;
    };
    
    LongCollection<float>::type m_foo;
    

    【讨论】:

    • 确实,复制你所有的演员??
    • 不,实际上你没有。这个习语称为“模板元函数”,其中嵌套的 ::type 是创建的实际类型。这意味着您并没有真正构建 LongCollection<...> 的实例,而是从 LongCollection<...>::type 中获取正确的类型。
    【解决方案2】:

    如果您不想采用宏方式,则必须为每种类型创建单独的 typedef:

    typedef std::vector< boost::shared_ptr< LongClassName<float> > > FloatCollection;
    typedef std::vector< boost::shared_ptr< LongClassName<double> > > DoubleCollection;
    

    【讨论】:

    • 这毕竟是 std::string 是 std::basic_string 的 typedef。
    【解决方案3】:

    不,但您可以使用“助手”类型接近,请参阅example

    【讨论】:

      【解决方案4】:

      Leon 给出的解决方案是规范的。一点背景知识:这被称为“(模板)元函数”,因为它基本上是一个在编译时被评估的“函数”。它处理类型而不是值:有一个输入类型列表(类型参数)和一个“返回值”:声明类型名称“type”的 typedef。

      “调用”的工作方式类似于正常的函数调用,尽管语法不同:

      // Normal function
      result = f(args);
      
      // Metafunction
      typedef f<args>::type result;
      

      这种代码结构是 Boost 库等库中甚至在 STL 中的一个常用习惯用法:allocator_type::rebind&lt;U&gt;::other 完成同样的事情,唯一的区别是 typedef type 被称为 other .

      【讨论】:

        【解决方案5】:

        这不完全是您要求的,但这可能会根据您的实际情况达到预期的效果:

        template <typename myfloat_t>
        class LongClassName
        {
            // ...
        };
        
        template <typename myfloat_t>
        class LongCollection : public std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > 
        {
        };
        

        您可能需要根据需要添加一些构造函数或运算符。

        【讨论】:

        • 派生自 STL 集合不被认为是不好的吗?它们没有虚函数。我认为通过使用 is 作为成员变量来根据 std::vector 实现 LongCollection 会更安全。私有继承也可能是一种选择。
        • 这不是好的做法,但只要您不打算使用多态,它实际上不会造成您提到的问题。
        猜你喜欢
        • 2011-02-17
        • 2011-09-26
        • 1970-01-01
        • 2011-06-27
        • 1970-01-01
        • 2013-01-23
        相关资源
        最近更新 更多