Tablica function pointers dla function template

0

Witam, wpierw chciałbym podziękować tym którzy poświęcili czas aby pomoc mi w rozwiązaniu problemu.

Problem był pewnie niejednokrotnie tematem wielu rozmów, ale miałem problem w znalezieniu jednoznacznej odpowiedzi zatem postanowiłem napisać nowy wątek.

W "normalnym" przypadku, kiedy chcę użyć pointerów (bądź array) do funkcji robię to mniej więcej w ten sposób:
Przykład dla dwóch sortowań

//****************************************
// SelectSort
    void SelectSort(int t[],int n){
        int temp;
        for(int i=0;i<n-1;i++){
            temp=i;
            for(int j=i+1;j<n;j++) if(t[j] < t[temp]) temp=j;
            swap(t[temp],t[i]);}
        return;}
//****************************************
// BubbleSort
    void BubbleSort(int t[], int n){
        for(int i=0; i<n-1; i++){
            for(int j=n-1; j>=i+1; j--){
                if(t[j] < t[j-1])
                    swap(t[j], t[j-1]);
            }
        }
    return;   
    }

void callFunc(int *t, int n, void(*pWhichFunc)(void)){return pWhichFunc(t,x);}
void (*pFoo)(int*,int) = {&SelectSort, &BubbleSort}

Jak stworzyć taką tablicę dwu elementową (tablice pointerów) kiedy użyjemy template'a? Przykładowo, jak napisać poprawnie żądaną operację dla tych samych sortowań tylko w przypadku kiedy zastosowałem wspomnianego template'a:

//****************************************
// SelectSort
template <class T>
    void SelectSort(T t[],int n){
        T temp;
        for(int i=0;i<n-1;i++){
            temp=i;
            for(int j=i+1;j<n;j++) if(t[j] < t[temp]) temp=j;
            swap(t[temp],t[i]);}
        return;}
//****************************************
// BubbleSort
template <class T>
    void BubbleSort(T t[], int n){
        for(int i=0; i<n-1; i++){
            for(int j=n-1; j>=i+1; j--){
                if(t[j] < t[j-1])
                    swap(t[j], t[j-1]);
            }
        }
    return;   
    }

// array pointer here - but how to do this? ; (

Słyszałem, iż nie jest to takie proste, ponieważ w takim przypadku jest to pointer to function template, a nie template function.
Z góry dziękuję za wszelką pomoc.

1

W sumie ciekawy temat. Można co najwyżej uzyskać wskaźnik do instancji szablonu, po wyspecyfikowaniu konkretnego typu. Poniżej przykładowy kod, który sobie testowo napisałem bazując na twoim poście. Są tam "twoje" metody sortujące, a niżej tworzenie dwuelementowych tablic wskaźników do funkcji (najpierw dla wersji nieszablonowej, potem szablonowych).


#include "stdafx.h"
#include <iostream>

using namespace std;

void SelectSort(int* t, int n)
{
	int temp;
	for(int i=0;i<n-1;i++)
	{
		temp=i;
		for(int j=i+1;j<n;j++)
			if(t[j] < t[temp])
				temp=j;
		
		swap(t[temp],t[i]);
	}
}

void BubbleSort(int* t, int n)
{
	for(int i=0; i<n-1; i++)
	{
		for(int j=n-1; j>=i+1; j--)
		{
			if(t[j] < t[j-1])
				swap(t[j], t[j-1]);
		}
	}
}

void (*pFunc[2])(int* t, int n) = {&SelectSort, &BubbleSort}; //nasza tablica wskaźników do funkcji nieszablonowych

template <typename T>
void SelectSortT(T* t, int n)
{
	int temp;
	for(int i=0;i<n-1;i++)
	{
		temp=i;
		for(int j=i+1; j<n; j++)
			if(t[j] < t[temp])
				temp=j;

		swap(t[temp],t[i]);
	}
}

template <typename T>
void BubbleSortT(T* t, int n)
{
	for(int i=0; i<n-1; i++)
	{
		for(int j=n-1; j>=i+1; j--)
		{
			if(t[j] < t[j-1])
				swap(t[j], t[j-1]);
		}
	}  
}


//tworzymy tablice wskaźników do instancji szablonów funkcji
//template <typename T>
//void (*pFuncT[2])(T* t, int n) = {&SelectSortT, &BubbleSortT}; - takie coś nie zadziała
void (*pFuncT[2])(int* t, int n) = {SelectSortT, BubbleSortT}; //ale można mieć wskaźnik do instancji szablonu po wyspecyfikowaniu typu
void (*pFuncTf[2])(float* t, int n) = {SelectSortT<float>, BubbleSortT<float>}; //drugi sposób

const int TAB_SIZE = 5;
int tab[TAB_SIZE] = {5, 4, 3, 2, 1};
float tabf[TAB_SIZE] = {5.1f, 4.1f, 3.1f, 2.1f, 1.1f};

template <typename T>
void printTabT(T* t, int n)
{
	for(int i=0; i <n; ++i)
		cout<<t[i]<<" ";

	cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	printTabT(tab, TAB_SIZE);
	pFuncT[0](tab, TAB_SIZE);
	printTabT(tab, TAB_SIZE);

	printTabT(tabf, TAB_SIZE);
	pFuncTf[1](tabf, TAB_SIZE);
	printTabT(tabf, TAB_SIZE);
	return 0;
}

1

Można też tak:

template <typename T> 
class foo
{
public:
	typedef void (*pfn_type)(T*, int);
	
	static pfn_type pFuncT[];
};

template <typename T> 
typename foo<T>::pfn_type foo<T>::pFuncT[2] = { &SelectSortT, &BubbleSortT };

...

const	int TAB_SIZE = 5;
int		tab[TAB_SIZE] = {5, 4, 3, 2, 1};
float	tabf[TAB_SIZE] = {5.1f, 4.1f, 3.1f, 2.1f, 1.1f};



foo<float>::pFuncT[0](tabf, TAB_SIZE);

foo<int>::pFuncT[1](tab, TAB_SIZE);
0

Jestem bardzo wdzięczny za pomoc i poświęcony czas w rozwiązaniu problemu. Teraz wszystko działa jak należy! Dzięki chłopaki D;

1 użytkowników online, w tym zalogowanych: 0, gości: 1