c++ - 如何专门化另一个模板类的模板成员函数?

标签 c++ visual-studio-2010 templates

我试图在堆类中为 DijkstraState 类创建专门的成员函数,但是当我编译和运行时出现错误我不知道我是否以错误的方式专门化了 addElement、reheapdown、siftup

这是我的代码

#ifndef HEAP_H
#define HEAP_H

#include "DijkstraState.h"
template <class T> class Heap
{
private:
    T* container; //Points to the array in which heap is implemented
    int counter; //Number of full places
public:
    Heap(int size=100)
    {
        container = new T[size]; 
        counter = 0; 
    }
    ~Heap()
    {
        delete[] container;
    }
    bool isEmpty()
    {
        return (counter == 0) ;
    }
    void reHeapDown(int i);
    void siftUp(int i);
    void addElement(T x);
    T& removeMin();
    T& getMin();
};


template <class T> void Heap<T>::siftUp(int i)
{
    while(true)
    {
        int parent = (i-1)/2 ;
        if(parent < 0 )
        {
            break ;
        }

        if(container[i] < container[parent]) //element is smaller than its parent then swap
        {
            T temp = container[parent] ;
            container[parent] = container[i] ;
            container[i] = temp ;
            i = parent ;
            //set the index of the parent
        }
        else
        {
            break ;
        }
    }
}

template <>
void Heap<DijkstraState<class T>>::siftUp(int i)
{
   while(true)
    {
        int parent = (i-1)/2 ;
        if(parent < 0 )
        {
            break ;
        }

        if(container[i] < container[parent]) //element is smaller than its parent then swap
        {
            DijkstraState<T> temp = container[parent] ;
            temp.setIndex(i) ;
            container[parent] = container[i] ;
            container[parent].setIndex(parent) ;
            container[i] = temp ;
            i = parent ;
            //set the index of the parent
        }
        else
        {
            break ;
        }
    }
}

template <class T> void Heap<T>::reHeapDown(int i)
{
    int smallestChild;
    while(true)
    {
        int child1 = (2*i) + 1 ;
        int child2 = (2*i) + 2 ;

        if(child1 >= counter) // an element with no children
        {
            break;
        }

        if(child2 >= counter) //element has only one child
        {
            smallestChild = child1 ;
        }
        else if(container[child1] <= container[child2]) //first child is smaller than or equal second child
        {
            smallestChild = child1 ;
        }
        else
        {
            smallestChild = child2 ;
        }

        if(container[i] < container[smallestChild]) //parent is greater than or equal smallest child.
        {
            break ;
        }

        T temp = container[smallestChild] ;
        container[smallestChild] = container[i] ;
        container[i] = temp ;
        i = smallestChild ;
        //set the index of the child and parent
    }
}

template <>
void Heap<DijkstraState<class T>>::reHeapDown(int i)
{
    int smallestChild;
    while(true)
    {
        int child1 = (2*i) + 1 ;
        int child2 = (2*i) + 2 ;

        if(child1 >= counter) // an element with no children
        {
            break;
        }

        if(child2 >= counter) //element has only one child
        {
            smallestChild = child1 ;
        }
        else if(container[child1] <= container[child2]) //first child is smaller than or equal second child
        {
            smallestChild = child1 ;
        }
        else
        {
            smallestChild = child2 ;
        }

        if(container[i] < container[smallestChild]) //parent is greater than or equal smallest child.
        {
            break ;
        }

        DijkstraState<T> temp = container[smallestChild] ;
        temp.setIndex(i) ;
        container[smallestChild] = container[i] ;
        container[smallestChild].setIndex(smallestChild) ;
        container[i] = temp ;
        i = smallestChild ;
        //set the index of the child and parent
    }
}


template <class T> void Heap<T>::addElement(T x)
{
    container[counter] = x ; //put the element in the last place in the array
    int i = counter ; //index of the added element
    counter++ ; //increase number of occupied places

    if(counter == 1) //special case: empty heap
    {
        //set index of the newly added element
        return;
    }

    siftUp(i);
}

template <>
void Heap<DijkstraState <class T>>::addElement(DijkstraState<T> x)
{
    container[counter] = x ; //put the element in the last place in the array
    int i = counter ; //index of the added element
    container[counter].setIndex(i);
    counter++ ; //increase number of occupied places

    if(counter == 1) //special case: empty heap
    {
        //set index of the newly added element
        return;
    }

    siftUp(i);
}


template <class T> T& Heap<T>::removeMin()
{
    if(isEmpty())
    {
        return -1;  
    }
    else
    {
        T min = container [0] ; //get the first element
        container[0] = container[--counter] ; //set the last element to the first element and decrease counter by one 

        reHeapDown(0) ;

        return min ;
    }
}

template <class T> T& Heap<T>::getMin()
{
    return container[0];
}

#endif

这些是产生的错误

1>  main.cpp
DijkstraState.h(12): error C2079: 'DijkstraState<T>::d' uses undefined class 'T'
 with
1>          [
1>              T=T
1>          ]
1>          c:\users\fakhr el din\documents\visual studio 2010\projects\dijkstra's_algorithm\dijkstra's_algorithm\Heap.h(68) : see reference to class template instantiation 'DijkstraState<T>' being compiled
1>          with
1>          [
1>              T=T
1>          ]

最佳答案

你的问题是这个类是模板化的(即,成员函数不是)因此你不能特化你需要的函数来特化这个类。但是,您可以配置它,使成员函数根据模板函数(或其他类似技术,这将允许您专门化实现的一个子集)来实现,此时您可以完全专门化 或重载函数。以下代码可能不是您需要的,但可以说明这一点。它使用一个独立函数和一个私有(private)嵌套类(可以用要修改的类状态实例化)。

示例代码

#include <iostream>

template<typename T>
void bar()
{
    std::cout << "general Foo::bar()\n";
}

template<>
void bar<int>()
{
    std::cout << "specialized Foo::bar()\n";
}

template<typename U>
struct Bar2Impl
{
    static void bar2() { std::cout << "general Foo::bar2()\n"; }
};

template<>
struct Bar2Impl<int>
{
    static void bar2() { std::cout << "specialized Foo::bar2()\n"; }
};

template<typename T>
class Foo
{
private:

public:
    void bar() { ::bar<T>(); }

    void bar2() { Bar2Impl<T>::bar2(); }
};

int main()
{
    Foo<double> f1;
    f1.bar();
    f1.bar2();

    Foo<int> f2;
    f2.bar();
    f2.bar2();

    return 0;
}

示例输出

general Foo::bar()
general Foo::bar2()
specialized Foo::bar()
specialized Foo::bar2()

关于c++ - 如何专门化另一个模板类的模板成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29837533/

相关文章:

c++ - munmap_chunk() : invalid pointer in C++ program

c++ - 我应该检查什么 : cpu time or wall time?

c++ - 如何在类 .h 文件中使用静态常量来定义数组的长度?

c++ - 链接器找不到函数定义,LNK2001 未解析的外部符号

c++ - 模板基类的模板运算符重载

c++ - 为什么具有显式声明的 move 构造函数的类会失败 `std::is_move_constructible_v` ?

c++ - 获得绝对时间的更好方法?

c++ - 构建静态库 (.lib) VS 2010 Pro

c++ - 这段代码的编译是标准行为吗?

c# - MVC : pass parameter to view?