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