2

考虑以下代码:

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,使用stam(有stam1stam2)称其为无数次,甚至是小的性能改进(例如不使用间接)都是受欢迎的。

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

4

2 回答 2

3

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

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

于 2012-10-22T23:28:14.340 回答
0

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

阅读有关指向成员函数的指针的教程:

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

于 2012-10-22T23:11:27.407 回答