简体   繁体   English

C ++模板方法

[英]C++ template method

I've written a simplified version of the STL basic_string class : 我已经编写了STL basic_string类的简化版本:

template<typename chrT>
class strT
{
protected:

    chrT * m_pcBuf;

    size_t m_nLen;

public:

    strT( void );

    strT( const chrT * pcStr );

    strT( const strT<chrT> & rsStr );

    virtual ~strT( void );

    virtual inline size_t len( void ) const;

    virtual int cmp( const strT<chrT> & rsStr ) const;

    virtual inline const chrT & operator [] ( size_t nPos ) const;

    virtual inline chrT & operator [] ( size_t nPos );

    virtual bool & operator == ( const strT<chrT> & rsStr ) const;

    virtual bool & operator != ( const strT<chrT> & rsStr ) const;

    virtual bool & operator < ( const strT<chrT> & rsStr ) const;

    virtual bool & operator > ( const strT<chrT> & rsStr ) const;

    virtual bool & operator <= ( const strT<chrT> & rsStr ) const;

    virtual bool & operator >= ( const strT<chrT> & rsStr ) const;

    virtual inline strT<chrT> & operator = ( const strT<chrT> & rsStr );

    virtual inline operator chrT * ( void );

protected:

    void _alloc( size_t nLen );

    void _realloc( size_t nLen );

public:

    static const size_t none;
};

template<typename inchr, typename outchr>
strT<outchr> convert( const strT<inchr> & rsIn );

typedef strT<char> str;
typedef strT<wchar_t> wstr;

Currently, if i want to convert between, say, char and wchar_t, i can simply do : 当前,如果我想在char和wchar_t之间进行转换,我可以简单地做到:

int main( void )
{
    str as = "foo";
    wstr ws = convert<char, wchar_t>( as );
}

But instead of this functionnal approach i would like to have a template method allowing to do such conversions. 但是,我希望使用一种模板方法来进行这种转换,而不是使用这种功能方法。 This is very likely false, but here is what i'd like to do : 这很可能是错误的,但这是我想做的事情:

template<typename chrT>
class strT
{
    // ...

public:

    template<typename outchr>
    virtual strT<outchr> convert( void ) const;

    // ...
}

template<typename chrT, typename outchr>
strT<outchr> strT<chrT>::convert<outchr>( void ) const
{
    // ...
}

And then : 接着 :

int main( void )
{
    str as = "foo";
    wstr ws = as.convert<wchar_t>();
}

Is it possible please ? 可以吗?

Thanks for your help ! 谢谢你的帮助 !

PS : Forgot to mention that i don't want to use C++11 features. PS:忘了提到我不想使用C ++ 11功能。

It's almost possible - you can have a member function template, but it cannot be virtual . 这几乎是可能的-您可以具有成员函数模板,但不能是virtual So if that's fine with you, drop virtual from the declaration and you're set. 因此,如果您满意,请从声明中删除virtual并设置好。

To see why member function templates can't be virtual , think about the most common implementation of virtual member functions - the virtual function table. 要了解为什么成员函数模板不能是virtual ,请考虑虚拟成员函数的最常见实现-虚拟函数表。 That's a table of pointers to functions, storing one pointer for each virtual function. 那是一个指向函数的指针表,为每个虚函数存储一个指针。 How many pointers would need to be stored for a virtual member function template? 虚拟成员函数模板需要存储多少个指针? One for convert<char> , one for convert<wchar_t> , one for convert<int> , one for convert<int*> , one for convert<int**> , one for convert<std::vector<int> > , one for ... 一个用于convert<char> ,一个用于convert<wchar_t> ,一个用于convert<int> ,一个用于convert<int*> ,一个用于convert<int**> ,一个用于convert<std::vector<int> > ,一个...

The problem is that arbitrarily many functions can be instantiated from the template. 问题在于可以从模板中实例化许多功能。 There's no way to do dynamic dispatch for them. 无法对其进行动态调度。 (Note that a similar problem appears in all other dynamic dispatch implementations as well - a template is just potentially infinitely many functions) (请注意,所有其他动态调度实现中也会出现类似的问题-模板可能具有无限多个功能)

Why not just add a templated constructor? 为什么不只是添加模板化的构造函数?

template<typename chrT>
class strT
{
public:
    template<typename otherT>
    strT(otherT* o) { ... }
}

To implement the conversion, you can specialize the constructor for the different possibilities of chrT and otherT 要实现转换,您可以专门针对chrTotherT的不同可能性chrT otherT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM