免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 10027 | 回复: 9
打印 上一主题 下一主题

[函数] 用函数指针将模板特例化:'...'cannot appear in a constant-expression [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-26 17:25 |只看该作者 |倒序浏览
问题:
我写了一个模板,需要一个函数指针作为模板差数,但是特例化时,向其传入一个函数名的时候却出现了如下的错误:
'...'cannot appear in a constant-expression
代码如下:

  1. #include <vector>
  2. #include <iterator>
  3. template <typename T, bool (*compare)(const T&,const T&)>
  4. class Base
  5. {
  6.         public:
  7.                 int search(const T& in, T* out );
  8.         private:
  9.                 std::vector<T> elems;
  10. };

  11. template <typename T, bool (*compare)(const T&,const T&)>
  12. int Base<T,compare>::search(const T& in, T* out)
  13. {
  14.         std::vector<T>::iterator iter;

  15.         for(iter = elems.begin() ; iter < elems.end(); iter++ )
  16.         {
  17.                 if( *compare(*iter,in) )
  18.                 {
  19.                         out = iter;
  20.                 }
  21.         }
  22. }

  23. class CashMgr{
  24.         public:
  25.                 bool compare(const int & item1,const int & item2);
  26.         private:
  27.                 Base<int,compare> x;
  28. };

  29. bool CashMgr::compare(const int & item1,const int & item2)
  30. {
  31. if(item1 == item2) return true;
  32. }
复制代码

编译结果如下:

  1. [who@Test]$ g++ -g  testTemplate_funcPointer.cpp
  2. testTemplate_funcPointer.cpp: In member function `int Base<T, compare>::search(const T&, T*)':
  3. testTemplate_funcPointer.cpp:15: error: expected `;' before "iter"
  4. testTemplate_funcPointer.cpp:17: error: `iter' was not declared in this scope
  5. testTemplate_funcPointer.cpp: At global scope:
  6. testTemplate_funcPointer.cpp:30: error: `bool CashMgr::compare(const int&, const int&)' cannot appear in a constant-expression
  7. testTemplate_funcPointer.cpp:30: error: template argument 2 is invalid
  8. testTemplate_funcPointer.cpp:30: error: ISO C++ forbids declaration of `x' with no type
复制代码

另外,这样的定义怎么也错了呢?
  1.   std::vector<T>::iterator iter;
复制代码

论坛徽章:
0
2 [报告]
发表于 2007-01-26 17:36 |只看该作者
std::vector<T>::iterator iter;
改为
typename std::vector<T>::iterator iter;

论坛徽章:
0
3 [报告]
发表于 2007-01-29 09:13 |只看该作者
能讲解一下原因吗?
另外开始那个编译错误呢?
-----已经修改后的程序和编译结果:

  1. #include <vector>
  2. #include <iterator>
  3. template <typename T, bool (*compare)(const T&,const T&)>
  4. class Base
  5. {
  6.         public:
  7.                 int search(const T& in, T* out );
  8.         private:
  9.                 std::vector<T> elems;
  10. };

  11. template <typename T, bool (*compare)(const T&,const T&)>
  12. int Base<T,compare>::search(const T& in, T* out)
  13. {
  14.         typename    std::vector<T>::iterator iter;

  15.         for(iter = elems.begin() ; iter < elems.end(); iter++ )
  16.         {
  17.                 if( *compare(*iter,in) )
  18.                 {
  19.                         out = iter;
  20.                 }
  21.         }
  22. }

  23. class CashMgr{
  24.         public:
  25.                 bool compare(const int & item1,const int & item2);
  26.         private:
  27.                 Base<int,compare> x;
  28. };

  29. bool CashMgr::compare(const int & item1,const int & item2)
  30. {
  31. if(item1 == item2) return true;
  32. }
复制代码

  1. [who@S-TradingServer Test]$ g++ -g testTemplate_funcPointer.cpp
  2. testTemplate_funcPointer.cpp:30: error: `bool CashMgr::compare(const int&, const int&)' cannot appear in a constant-expression
  3. testTemplate_funcPointer.cpp:30: error: template argument 2 is invalid
  4. testTemplate_funcPointer.cpp:30: error: ISO C++ forbids declaration of `x' with no type
复制代码

论坛徽章:
0
4 [报告]
发表于 2007-01-29 09:46 |只看该作者
你也许应该把compare声明为了static,否则用不了

论坛徽章:
0
5 [报告]
发表于 2007-01-29 11:45 |只看该作者
原帖由 xb_parasite 于 2007-1-29 09:13 发表
能讲解一下原因吗?
另外开始那个编译错误呢?
-----已经修改后的程序和编译结果:
[code]
#include <vector>
#include <iterator>
template <typename T, bool (*compare)(const T&,co ...


typename的解释在这里:
http://www.cppblog.com/converse/archive/2006/03/22/4476.html

论坛徽章:
0
6 [报告]
发表于 2007-01-29 13:17 |只看该作者
谢谢converse。
tyc611
能简单讲解一下原因吗。

论坛徽章:
0
7 [报告]
发表于 2007-01-29 14:15 |只看该作者
原帖由 xb_parasite 于 2007-1-29 13:17 发表
谢谢converse。
tyc611
能简单讲解一下原因吗。

简单点:
1. typename关键字向编译器声明它后面的是一个类型,因为对于类中的类型成员,编译器可能误认为是数据成员,converse版主已经给了一个链接给你,你应该仔细看看,想想
2. 当特化模板时,非类类型模板参数需要一个编译时能确定的常量来特化,而你的非static类成员函数是一个运行时才能完全确定的东西,只有static成员函数才能在编译时确定。你上面的代码似乎应该是Base<int, CashMgr::compare> x;

论坛徽章:
0
8 [报告]
发表于 2007-01-29 14:36 |只看该作者
好的。
那个链接俺会好好看看的。
8用谢咯。

论坛徽章:
0
9 [报告]
发表于 2007-01-29 14:37 |只看该作者
原帖由 xb_parasite 于 2007-1-29 14:36 发表
好的。
那个链接俺会好好看看的。
8用谢咯

论坛徽章:
0
10 [报告]
发表于 2007-01-29 17:30 |只看该作者
不是bug啦。
故意的。
呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP