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

时间:2012-10-22 22:48:08

标签: 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 %d\n", 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获取一个地址。因此,地址在编译时是不恒定的(尽管可能有一些工作 - 但是不支持)。

那我为什么要这样做呢。我可以使用函数指针或虚函数。实际上,使用bla stamstam1stam2)的bla1称它为Zillion次,即使是次要的性能改进(例如不使用间接)也是受欢迎的。

当然有解决方案:创建bla2和{{1}}几乎完全相同。编写预处理器宏。我想知道是否有一个优雅的解决方案。

2 个答案:

答案 0 :(得分:3)

编译好了:

#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 %d\n", xx.f());
  return 0;
}

修复方法是使用指针到方法模板参数的正确签名和指定方法指针的正确语法。 (事实上​​,你可以在那里省略<A>。)

答案 1 :(得分:0)

问题是stam()是一个成员函数,而不是一个自由函数,因此需要用“this”指针调用它。

阅读本教程,了解有关成员函数的指示:

http://www.parashift.com/c++-faq/pointers-to-members.html