Использование C ++ 0x:
namespace {
template<class T> struct Template { };
}
typedef Template<int> Template;
#include<iostream>
template<typename T>
void PrintType() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<typename FullType, typename NewParameter>
class Rebind {
template<template<class> class Template, typename OldParameter>
static Template<NewParameter> function(Template<OldParameter>);
public:
typedef decltype(function(FullType())) NewType;
};
int main()
{
PrintType< ::Template>();
PrintType<Rebind< ::Template, float>::NewType>();
return 0;
}
С gcc45, который дает
void PrintType() [with T = <unnamed>::Template<int>]
void PrintType() [with T = <unnamed>::Template<float>]
Очевидно, что он компилируется с Cormeau, но у меня есть доступ только к их онлайн-тесту, так что я застрял, только предполагая, что он работает должным образом.
Я не мог придумать, как передать фактический тип в структуру напрямую и сделать так, чтобы он превратился в шаблонный тип, но у компилятора не возникло проблем с их удалением, когда ему приходилось угадывать параметры функции. Возможно, это работает в C ++ 03 с использованием boost::result_of
вместо decltype
, но я никогда не использовал его раньше, поэтому решил, что буду придерживаться того, что знаю.
Обратите внимание на интервал в main
. Rebind<::Template, float>::NewType
получает парсер из-за того, что <:
является орграфом. Я думаю, что это превращается в Rebind[:Template, float>::NewType
. Так что пространство до ::Template
жизненно важно.
Кроме того, я понятия не имел, что вложенные параметры шаблона не могут использовать имя типа [template<template<typename> class T>
вместо template<template<typename> typename T>
]. Я думаю, что переучиваю это каждый раз, когда пытаюсь запомнить синтаксис конструкции.