《C++ primer》学习笔记之七:常见编译错

8 常见编译错:
 1. 如果一个const对象访问一个非const成员函数会报错:C2662: “Example2<elemType>::print” : 不能将“this”指针从“const Example2<elemType>”转换为“Example2<elemType> &”
    msdn的解释:Invoking a non-const member function on a const object.
   
     
 4. 在函数定义之前调用函数引起的错误:
   using namespace std;
   cout << "begin at" << getTimeStr() << endl;
   char * getTimeStr(){ return "2006/04/01" };
  本想编译的错误是:函数未定义,但实际出现三个错误:
   1. error C2365: “getTimeStr” : 重定义;以前的定义是“原先未知的标识符”
    msdn解释为:'class member' : redefinition; previous definition was a 'class member'
    比如:
     class C1
     {
        int CFunc();
        char *CFunc;    // C2365, already exists as a member function
     
        int CMem;
        char *CMem();   // C2365, already exists as a member
     };
     
    这个编译错很是奇怪,怀疑是getTimeStr这个名字特殊,改为getTimeStr22后仍然如此。
   2. error C2593: “operator <<”不明确
    操作符'<<'在namespace std中定义了很多,由于函数getTimeStr的定义找不到,所以无法知道函数的返回值
    这是overload函数引起的
   3. error C3861: “getTimeStr22”: 即使使用参数相关的查找,也未找到标识符
    这个才是真正的错误。
  将getTimeStr()的定义移到前面就好了。不过error1还是没有搞清楚为何会出现。

 6. template引起的编译错误非常难懂:
  (1)如果使用模板类而没有include该类的头文件会出现下面错: 
    
     vector< int > _stack;  //使用vector类
     
    d:/len/begin3/iStack.h(31): error C2143: 语法错误 : 缺少“;”(在“<”的前面)
   原因:编译器不知道vector标识符为一个模板的名字,所以引起后面的template parameter解析出错
   解决办法:#include <vector> //将vector的头文件include进来

  (2) template function引起的符号找不到link错:
   场景:
     //in common.h
     template<class T> void myprint(T); //just declare in header
     
     //in common.cpp      //define in .cpp
     #include "common.h"
     template<class T> void myprint(T t){ cout << t <<endl; }
     
     //in test.cpp
     #include "common.h"
     int main(){ myprint(100); return 0; }
     
   link error: myprint<int>(int)找不到定义
   原因:template compilation model有两种:inclusion model 和 separate model
     VC 使用inclusion model,它要求template的定义在每个使用它的文件中都被include,一般将template的定义放在header中。
     (separate model则像普通函数一样处理,将delare放在header中,然后在cpp中定义它,但千万注意:定义时要使用export关键字。)
   解决办法:
    1. 在common.cpp中定义myprint时加上export关键字,为:
      export template<class T> void myprint(T){ cout << T <<endl; }
     不过VC不支持export关键字,作罢。
    2. 将定义放在common.h中:
      //in common.h
      template<class T> void myprint(T){ cout << T <<endl; }
     正确运行,但是有潜在的错误:如果common.h被include两次,则会出现"myprint已定义“的编译错误
     修正:
      //in common.h
      #ifndef common_h  //可以用precompile指令#pragma once来代替这种技巧
      #def common_h
      template<class T> void myprint(T){ cout << T <<endl; }
      #endif
  (3)error C2664: “void std::sort<std::vector<_Ty>::iterator>(_RanIt,_RanIt)” : 不能将参数 2 从“std::vector<_Ty>::const_iterator (void) const”转换为“std::vector<_Ty>::iterator”
    场景: 
     vector<string> line;
     std::sort<Line::iterator>(line.begin(), line.end);  //注意:函数调用end错误,应为end()
   原因:调用参数的类型和 模板参数的类型不匹配
    错误的函数调用end,使得:第一个调用参数类型为std::vector<_Ty>::iterator
           第二个调用参数类型为std::vector<_Ty>::const_iterator (void) const (函数指针类型)
   由错误的现象很难看到错误的原因。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值