如何为非模板类​​定义模板方法?

时间:2011-01-18 12:11:09

标签: c++ visual-studio templates methods implementation

我的编译器对我实现模板方法的方式不满意。它为这些实现提供了错误消息,如“未定义类型T”。

这是我的第一个方法,它是在类块之外实现的:

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

另一个就是这个;这次方法是在类中实现的:

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);
        }
        // ...
}

我的代码有什么问题,或者这只是编译器本身的问题?

IDE&amp;编译器:Visual Studio 2010

5 个答案:

答案 0 :(得分:5)

您的代码看起来不错。但有一件事在我脑海中浮现。你可以检查之前是否定义了“sign”功能?只需将鼠标悬停在其上即可。 C运行时库使用“#define”关键字实现它的一些功能,因此你不能在之后定义具有相同名称的函数。

答案 1 :(得分:4)

你错过了一些typename和分号,但除此之外,代码似乎没问题。恕我直言,是时候提交一个bug,如果它仍然不起作用。

顺便说一下,使用std::swap更好地完成交换代码。

答案 2 :(得分:1)

您的代码在VS2005上编译时没有错误(除了在ElementaryMath定义结尾处缺少分号),因此您可能正在查看编译器错误。

VS2010 SP1在测试版here中可用。可能有帮助,但显然是它的测试版......

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

希望这有帮助!