使用的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
之前的空间是至关重要的。另外,我不知道嵌套的模板参数不能使用typename [template<template<typename> class T>
而不是template<template<typename> typename T>
]。我想我每次尝试记住构造的语法时都会重新学习一下。
我使它成为社区维基,因为它实际上是一个有趣的好奇问题,而不是实际的东西。 :) – 2010-05-28 21:29:46
请注意,有*是*至少一个解决方案的第二个问题,编译所有ng/gcc/comeau,但它只是更难以发现:) – 2010-05-28 22:09:27
我没有时间充分考虑这一点,但是不要使用分配器来改变模板参数吗?你能不能在这里做类似的事情,并且最终得到一些类似于'Rebind <:: Template,float> :: type'的东西?这样,'Template'将被重新命名,在'Rebind'中被称为'T',并且没有歧义。 – 2010-05-28 22:26:14