解决 VC++12 中的模板专业化错误?
Posted
技术标签:
【中文标题】解决 VC++12 中的模板专业化错误?【英文标题】:Work around for template specialization bug in VC++12? 【发布时间】:2014-02-07 22:25:02 【问题描述】:我有一些为 Clang 3.2 编写的代码,我正在尝试移植以在 VC++12 中运行。 Clang 3.2+ 和 GCC 4.8 没有问题,但是 VC++12 抱怨。这是产生问题的最小 sn-p:
template <int(*ptr)()>
class foo ;
template<int N>
int ReturnsN() return N;
template<int N>
class bar
typedef foo<ReturnsN<N>> fooN;
;
现在我很确定这是一个编译器错误(但如果不是,请告诉我!)给出的错误是:
'specialization' : cannot convert from 'int (__cdecl *)(void)' to 'int (__cdecl *)(void)'
那么有没有人知道一个体面的工作?编译器似乎确信专用函数没有完全定义。
编辑:我还应该注意,我已经使用股票编译器和 2013 年 11 月的 CTP 进行了尝试。两者都有同样的问题。
【问题讨论】:
我很想知道删除inline
是否有任何不同。
@WhozCraig 哦,对不起,它没有。我认为确实如此,并将其从我的测试项目中删除。将编辑我的问题。
我猜你也试过foo<&ReturnsN<N>>
? (如果可行,我现在就开始出售我的 MS 股票)。 (另外,我在这里没有看到专业化;只有实例化)。
@WhozCraig 不幸的是,我确实尝试过。我相信任何可行的解决方法都必须以某种方式模拟模板参数,因为用文字或可见的 static const int
替换 <N>
可以正常工作。
我的目前还没有启动和运行。 VC2012/2013是否实现了模板别名?
【参考方案1】:
一个可悲的解决方法,我建议您向connect 提交错误报告:
template < int (*)() >
class foo ;
template<int N>
int ReturnsN( ) return N;
template<int N>
class bar
static int myReturnsN() return ReturnsN<N>;
using fooN = foo< myReturnsN >;
;
【讨论】:
我刚刚找到了相同的解决方法!不过我会给你积分,谢谢你的帮助。 Here's the bug report as well. VS2013 病了……而且这个甚至与花哨的参数包扩展之类的 c++11 支持无关……【参考方案2】:如果有人好奇,我发现了一个有点难看的解决方法。基本上只需要添加一个静态成员函数来隐藏函数,所以它不会尝试解析函数特化同时也解析函数指针模板参数:
template <int(*ptr)()>
class foo ;
template<int N>
int ReturnsN() return N;
template<int N>
class bar
private:
static int Hack()
return ReturnsN<N>();
public:
typedef foo<Hack> fooN;
;
这在所有 VS2012、VS2013 和 VS2013 十一月 CTP 中编译。
【讨论】:
【参考方案3】:另一种可能的解决方法是使ReturnsN
函数成为类模板的静态成员函数:
template <int(*)()>
class foo;
template <int N>
struct Wrapper
static int ReturnsN() return N;
;
template <int N>
class bar
typedef foo<Wrapper<N>::ReturnsN> fooN;
;
此代码在 VC++ 2013 中编译得很好。
【讨论】:
以上是关于解决 VC++12 中的模板专业化错误?的主要内容,如果未能解决你的问题,请参考以下文章