hkBattousai
hkBattousai

Reputation: 10911

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

Upvotes: 4

Views: 5057

Answers (5)

Andy Johnson
Andy Johnson

Reputation: 8149

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

Upvotes: 1

Mahesh
Mahesh

Reputation: 34615

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 !

Upvotes: 1

user579962
user579962

Reputation:

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.

Upvotes: 5

CashCow
CashCow

Reputation: 31435

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;
    }
}

Upvotes: 1

jpalecek
jpalecek

Reputation: 47762

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.

Upvotes: 4

Related Questions