2008-11-24 4 views
3

Рассмотрит следующее использование параметров шаблона шаблона ...Как объявить/определить класс с параметрами шаблона шаблона без использования дополнительного параметра шаблона

#include <iostream> 

template <typename X> 
class A 
{ 
    X _t; 
public: 
    A(X t) 
     :_t(t) 
    { 
    } 
    X GetValue() 
    { 
     return _t; 
    } 
}; 

template <typename T, template <typename T> class C > 
class B 
{ 
    C<T> _c; 
public: 
    B(T t) 
     :_c(t) 
    { 
    } 
    T GetValue() 
    { 
     return _c.GetValue(); 
    } 
}; 

using namespace std; 

int main() 
{ 
    B<int, A> b(10); 
    cout<<b.GetValue(); 
    return 0; 
} 

Есть ли способ, с помощью которого параметр шаблона T может быть удален? Например, есть ли способ сделать следующую работу?

//Does not compile 
template <template <typename T> class C > 
class B 
{ 
    C _c; 
public: 
    B(T t) 
     :_c(t) 
    { 
    } 
    T GetValue() 
    { 
     return _c.GetValue(); 
    } 
}; 

int main() 
{ 
    B< A<int> > b(10); 
    cout<<b.GetValue(); 
    return 0; 
} 

ответ

8

Я предполагаю, что вы после X, а также A, в своем коде.

Обычная картина иметь

template<typename C> 
struct B 
{ 
    C c; 
}; 

, а затем, внутри классов, имеющих право на замещение:

template<typename X> 
class A 
{ 
    typedef X type_name; 
    X t; 
}; 

Затем вы можете получить доступ к параметру с помощью шаблона C::type_name.

+0

Спасибо за ответ, хотя я в конце концов обнаружил это сам. Я был в процессе редактирования вопроса и публикации моей работы, но, видимо, я пришел в нужное место, чтобы задать этот вопрос! – 2008-11-24 14:05:07

+0

Обратите внимание, что ответ Солнечного света лучше моего, так как он понял, чего вы хотите. Не нужно переписывать, как я показал тебе.Это потребуется только в том случае, если вы используете A , но изредка нуждаетесь в этом или A . Или, если вид пользователя A , но вы используете A . – 2008-11-24 14:14:33

1

Что случилось с:

template <typename C > 
struct B 
{ 
    C c; 
}; 

int main() 
{ 
    B< A<int> > b; 
    return 0; 
} 
+0

Плохо, проблема не была полностью определена. Теперь это. – 2008-11-24 14:06:41

4

Это не представляется возможным. Обратите внимание, что это распространенное недоразумение: A<int> больше не шаблон шаблона! Так что это не будет соответствовать параметру шаблона шаблона, но должны быть приняты с использованием типа-параметра:

template<typename C> 
struct B { 
    C c; 
}; 

B< A<int> > b; 

Ваш способ использования отдельного параметра в порядке.

Если вы хотите принять A<int> но хотите повторно связать его с другим параметром, вы можете использовать этот шаблон, используемый также стандартными-распределителей:

template<typename T> 
struct A { 
    template<typename U> 
    struct rebind { 
     typedef A<U> type; 
    }; 
}; 

template<typename C> 
struct B { 
    typename C::template rebind<float>::type c; 
}; 

B< A<int> > b; 

Теперь B< A<int> >::c имеет тип A<float>. typename до C:: сообщает компилятору, что ::type в конце является типом, а не статическим не-типом элементом. template после C:: сообщает компилятору, что rebind<float> - это экземпляр шаблона, а не сравнение.

+0

Хорошо круто! Хороший ответ, но, к сожалению, может быть только один ответ, и я думаю, @sunlight отправил свое решение раньше вам. Я поддержал ваш ответ. – 2008-11-24 14:14:28

1

Вы можете вложить параметры. То есть значение параметра может быть параметризовано.

template <typename X> 
struct A 
{ 
    X t; 
}; 

template <typename C> 
struct B 
{ 
    C c; 
}; 

int main() 
{ 
    B< A<int> > b; 
    return 0; 
} 

В этом примере, декларация b в main() создает специализацию A с использованием int в качестве параметра, то он создает специализацию B с использованием A<int> в качестве параметра. Таким образом, по специализации B, C составляет A<int>.