在模板类中:使用类方法作为另一类方法的模板参数

  • 本文关键字:类方法 参数 c++ templates
  • 更新时间 :
  • 英文 :


考虑以下代码:

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获取一个地址。因此,该地址在编译时并不恒定(尽管有些工作可能是 - 但这是不支持的)。

所以为什么我要这样做。我可以使用功能指针或虚拟功能。实际上,使用stambla(有stam1stam2)称其为亿万次,甚至是较小的性能改进(例如不使用间接)。

当然有解决方案:创建几乎相同的bla1bla2。写一个预处理器宏。我想知道是否有优雅的解决方案。

这会编译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

最新更新