解决 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&lt;&amp;ReturnsN&lt;N&gt;&gt; ? (如果可行,我现在就开始出售我的 MS 股票)。 (另外,我在这里没有看到专业化;只有实例化)。 @WhozCraig 不幸的是,我确实尝试过。我相信任何可行的解决方法都必须以某种方式模拟模板参数,因为用文字或可见的 static const int 替换 &lt;N&gt; 可以正常工作。 我的目前还没有启动和运行。 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 中的模板专业化错误?的主要内容,如果未能解决你的问题,请参考以下文章

g ++中的显式模板专业化导致麻烦

Clang 可变参数模板专业化错误:不可演绎的模板参数

抛出模板专业化错误的函数指针数组(包括成员函数)

如何解决这个问题(基础模板与继承)

VC++中的“已经定义”错误

类中的模板专业化[重复]