konkretyzacja szablonu szablonem

0

Załóżmy że mamy prostą funkcję szablonową:

template <typename T>
void foo(T t)
{
	cout << "foo<T>" << endl;
}

konkretyzacja typem prostym nie jest problemem:

template <>
void foo<int>(int t)
{
	cout << "foo<int>" << endl;
}

ani typem szablonowym:

template<>
void foo<vector<int>>(vector<int> t)
{
	cout << "foo<vector<int>>" << endl;
}

ale co jeśli chcemy użyć ogólnego vector<T>?
próbowałem na różne sposoby, np.

template<>
template<typename T>
void foo<vector<T>>(vector<T> t)
{
	cout << "foo<vector<T>>" << endl;
}

ale kompilator nie łyka.

da się to jakoś zrobić?

1

A tak bez uciekania w zbyt duży poziom abstrakcji i skomplikowania: jaki błąd ci wywala? Poprawiłem trochę twoją składnię:

 template<typename T>
 void foo<vector<T> >(vector<T> t)
 {
         cout << "foo<vector<T>>" << endl;
 }

gcc mi wywala:

azarien.cpp:24: error: function template partial specialization âfoo<std::vector<T, std::allocator<_CharT> > > is not allowed

Odwieczny problem gcc. Ale częściowa specjalizacja klas w gcc działa. Więc jeśli zamieni się funkcje na klasy zawierające statyczną publiczną metodę void foo(), to powinno działać.

0

Visual wywala:
C2768: 'foo' : illegal use of explicit template arguments

ale takie coś przechodzi

template<typename T>
void foo(vector<T> t)
{
        cout << "foo<vector<T>>" << endl;
}

Chociaż wydaje mi się, że kompilator to potraktuje jako przeciążoną funkcję, a nie konkretyzację szablonu. Ale czy to w czymś zaszkodzi?

2

Jak zauważa przedmówca jest to rodzaj problemu częściowej specjalizacji i można go rozwiązać przy pomocy klasy proxy:

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
struct foo_impl;

template <typename T>
void foo()
{
    foo_impl<T>();
}

/* T */
template <typename T>
struct foo_impl {
    foo_impl()
    {
        cout << "general" << endl;
    }
};

/* vector<T> */
template <typename T>
struct foo_impl< vector<T> > {
    foo_impl()
    {
        cout << "vec" << endl;
    }
};

/* pair<T1, T2> */
template <typename T1, typename T2>
struct foo_impl< pair<T1, T2> > {
    foo_impl()
    {
        cout << "pair" << endl;
    }
};

int main()
{
    foo<int>();
    foo< vector<int> >();
    foo< pair<int, int> >();
}

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