考虑以下代码:
template < class A >
class XX {
public:
template <int (*CC)() >
int bla (){ return CC(); }
int stam() {return 0;}
int f() {
return bla<stam>();
}
};
int main()
{
XX<int> xx;
printf(" this is %dn", xx.f());
return 0;
}
它在
上失败test.cpp: In member function ‘int XX<A>::f() [with A = int]’:
test.cpp:14: instantiated from here
test.cpp:8: error: ‘int XX<A>::stam() [with A = int]’ cannot appear in a constant-expression**
考虑到这一点很明显。在实例化模板之前,stam
不存在,因此它没有函数地址。当实例化模板时,该实例在代码中的某个地方进行了未充实,然后stam
获取一个地址。因此,该地址在编译时并不恒定(尽管有些工作可能是 - 但这是不支持的)。
所以为什么我要这样做。我可以使用功能指针或虚拟功能。实际上,使用stam
的bla
(有stam1
和stam2
)称其为亿万次,甚至是较小的性能改进(例如不使用间接)。
当然有解决方案:创建几乎相同的bla1
和bla2
。写一个预处理器宏。我想知道是否有优雅的解决方案。
这会编译OK:
#include <cstdio>
using namespace std;
template < class A >
class XX {
public:
template <int (XX<A>::*CC)()>
int bla (){ return (this->*CC)(); }
int stam() {return 0;}
int f() {
return bla<&XX<A>::stam>();
}
};
int main()
{.
XX<int> xx;
printf(" this is %dn", xx.f());
return 0;
}
修复程序是为指针到方法模板参数和正确的语法使用正确的签名来指定方法指针。(实际上,您可以在那里省略<A>
。)
问题是stam()是成员函数,而不是免费函数,因此需要用"此"指针调用。
阅读有关成员功能指针的本教程:
http://www.parashift.com/c -faq/pointers-to-members.html