开发者

How to define a template method for a non-template class?

My compiler is not happy with the way I implement my template methods. It gives tons of error messages like "undefined type T" for these implementations.

This is my first method, it is开发者_运维百科 implemented outside of the class block:

class VectorConvertor
{
    public:
        // ...
        template <class T>
        static void ReverseVectorElements(std::vector<T> & Vector);
        // ...
};

template <class T>
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector)
{
    std::vector<T>::size_type size = Vector.size();
    T swap;
    for (std::vector<T>::size_type i=0; i<size/2; i++)
    {
        swap = Vector.at(i);
        Vector.at(i) = Vector.at(size-1-i);
        Vector.at(size-1-i) = swap;
    }
}

Another one is this; this time the method is implemented inside the class:

class ElementaryMath
{
    public:
        // ...
        template <class T> static char sign(T num)
        {
            return (num >= static_cast<T>(0)) ? static_cast<char>(+1) : static_cast<char>(-1);
        }
        // ...
}

Is there anything wrong with my code, or is this just a problem with the compiler itself?

IDE & Compiler: Visual Studio 2010


Your code looks OK to me. But there is one thing that got in my mind. Can you please check if the function "sign" is defined before? Simply hover your mouse on it. C runtime library implements some of its functions using the "#define" keyword and because of that you can't define a function with that same name afterwards.


You're missing some typenames and semicolons, but otherwise, the code seems OK. IMHO it's time to file a bug if it still doesn't work.

BTW, the swapping code would be better done with std::swap.


typename here:

template <class T>
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector)
{
    typename std::vector<T>::size_type size = Vector.size();
    T swap;
    for (typename std::vector<T>::size_type i=0; i<size/2; i++)
    {
        swap = Vector.at(i);
        Vector.at(i) = Vector.at(size-1-i);
        Vector.at(size-1-i) = swap;
    }
}


class VectorConvertor
{
    public:
    // ...
    template <typename T>
    static void ReverseVectorElements(std::vector<T> & Vector);
};

template <typename T>
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector)
{
    std::vector<T>::size_type size = Vector.size();
    T swap;
    for (std::vector<T>::size_type i=0; i<size/2; i++)
    {
        swap = Vector.at(i);
        Vector.at(i) = Vector.at(size-1-i);
        Vector.at(size-1-i) = swap;
    }
}

int main()
{
    std::vector <int> i(10,0);

    VectorConvertor obj;   // Since your class isn't a template, template parameter
                           // isn't required for a class template instantiation.
                           // However, if your class was a template class, template-
                           // parameter must have been required for a class template
                           // instantiation.

    obj.ReverseVectorElements(i);  // Equal to obj.ReverseVectorElements<int>(i);
                                   // Based on type of i, compiler can instantiate a 
                                   // template function by default.
    getchar();
    return 0;
}

Hope this helps !


Your code compiles without error on VS2005 (apart from a missing semicolon at the end of the definition of ElementaryMath) so you may be looking at a compiler bug.

VS2010 SP1 is available in beta here. Might help, but obviously its beta...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜