简体   繁体   中英

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 typename s 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 .

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...

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 !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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