解决VC ++ 12中的模板特化问题?

时间:2014-02-07 22:25:02

标签: c++ visual-studio c++11 visual-studio-2013

我为Clang 3.2编写了一些代码,我试图移植到VC ++ 12中运行。 Clang 3.2+和GCC 4.8没有任何问题,但VC ++ 12抱怨。这是产生问题的最小代码段:

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。两者都有同样的问题。

3 个答案:

答案 0 :(得分:3)

如果有人好奇,我发现了一个有点难看的解决方法。基本上只需要添加一个静态成员函数来模糊函数,所以它也不会尝试解析函数特化而同时解析函数指针模板参数:

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 11月CTP。

答案 1 :(得分:3)

一个悲伤的解决方法,我建议您向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 >;
};

答案 2 :(得分:0)

另一种可能的解决方法是使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。