青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

模板類的子類訪問不到父類的成員變量問題

很少用模板類,今天用googlemock給一個(gè)api打樁,那個(gè)api的函數(shù)居然是nonvirutal的,gmock幫助手冊(cè)說(shuō)Mocking Nonvirtual Methods就得用模板類,所以改了源碼,加了模板。但是編譯時(shí)遇到錯(cuò)誤,原來(lái)都可以在子類成員函數(shù)中訪問到的父類的成員變量,現(xiàn)在提示沒有定義過。

比如

template<typename T>

class A

{

public: 

   virtual int foo(){return 0};

protected:

   int m_a;

};

template<typename T>

class B : public A<T>

{

public:

   virtual int foo() {return m_a;}

};

這樣用gcc就會(huì)報(bào)錯(cuò),B類的foo函數(shù)中m_a找不到。

解決辦法是 B類的foo函數(shù)這么寫

 virtual int foo() {return this->m_a;}

或者

 virtual int foo() {return A::m_a;}

原因請(qǐng)看這段話:

//10.8.2 Name lookup, templates, and accessing members of base classes
//The C++ standard prescribes that all names that are not dependent on template parameters
//are bound to their present definitions when parsing a template function or class.1 Only
//names that are dependent are looked up at the point of instantiation. For example, consider
//
//       void foo(double);
//
//       struct A {
//         template 
//         void f () {
//           foo (1);        // 1
//           int i = N;      // 2
//           T t;
//           t.bar();        // 3
//           foo (t);        // 4
//         }
//
//         static const int N;
//       };
//
//Here, the names foo and N appear in a context that does not depend on the type of T. The
//compiler will thus require that they are defined in the context of use in the template,
//not only before the point of instantiation, and will here use ::foo(double) and A::N,
//respectively. In particular, it will convert the integer value to a double when passing
// it to ::foo(double).
//
//Conversely, bar and the call to foo in the fourth marked line are used in contexts that
//do depend on the type of T, so they are only looked up at the point of instantiation,
//and you can provide declarations for them after declaring the template, but before
//instantiating it. In particular, if you instantiate A::f, the last line will call an
//overloaded ::foo(int) if one was provided, even if after the declaration of struct A.
//
//This distinction between lookup of dependent and non-dependent names is called two-stage
//(or dependent) name lookup. G++ implements it since version 3.4.
//
//Two-stage name lookup sometimes leads to situations with behavior different from non-template
//codes. The most common is probably this:
//
//       template  struct Base {
//         int i;
//       };
//
//       template  struct Derived : public Base {
//         int get_i() { return i; }
//       };
//
//In get_i(), i is not used in a dependent context, so the compiler will look for a name declared
//at the enclosing namespace scope (which is the global scope here). It will not look into the base
//class, since that is dependent and you may declare specializations of Base even after declaring
//Derived, so the compiler can't really know what i would refer to. If there is no global variable
//i, then you will get an error message.
//
//In order to make it clear that you want the member of the base class, you need to defer lookup
//until instantiation time, at which the base class is known. For this, you need to access i in a
//dependent context, by either using this->i (remember that this is of type Derived*, so is
//obviously dependent), or using Base::i. Alternatively, Base::i might be brought into scope
//by a using-declaration.
//
//Another, similar example involves calling member functions of a base class:
//
//       template  struct Base {
//           int f();
//       };
//
//       template  struct Derived : Base {
//           int g() { return f(); };
//       };
//
//Again, the call to f() is not dependent on template arguments (there are no arguments that depend on
//the type T, and it is also not otherwise specified that the call should be in a dependent context).
//Thus a global declaration of such a function must be available, since the one in the base class is
//not visible until instantiation time. The compiler will consequently produce the following error message:
//
//       x.cc: In member function `int Derived::g()':
//       x.cc:6: error: there are no arguments to `f' that depend on a template
//          parameter, so a declaration of `f' must be available
//       x.cc:6: error: (if you use `-fpermissive', G++ will accept your code, but
//          allowing the use of an undeclared name is deprecated)
//
//To make the code valid either use this->f(), or Base::f(). Using the -fpermissive flag will also
//let the compiler accept the code, by marking all function calls for which no declaration is visible
//at the time of definition of the template for later lookup at instantiation time, as if it were a
//dependent call. We do not recommend using -fpermissive to work around invalid code, and it will also
//only catch cases where functions in base classes are called, not where variables in base classes are
//used (as in the example above).
//
//Note that some compilers (including G++ versions prior to 3.4) get these examples wrong and accept above
//code without an error. Those compilers do not implement two-stage name lookup correctly.
//


原理是名字查找的規(guī)則問題。由于還要加班調(diào)程序,下次再寫名字查找的原理

posted on 2012-03-04 11:09 大龍 閱讀(2407) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产毛片久久| 亚洲欧美久久| 亚洲午夜精品一区二区| 91久久精品一区二区别| 先锋影院在线亚洲| 亚洲一级二级在线| 欧美欧美全黄| 欧美激情中文字幕乱码免费| 国产毛片精品视频| 亚洲在线观看视频| 一区二区三区四区五区视频 | 亚洲网址在线| 欧美激情亚洲自拍| 欧美成人免费网| 国内伊人久久久久久网站视频| 亚洲网址在线| 午夜精品电影| 国产精品久久久久国产精品日日| 亚洲人成人一区二区在线观看| 韩国av一区二区三区在线观看| 亚洲性色视频| 欧美一区二区| 国产亚洲激情| 久久精品91久久久久久再现| 欧美主播一区二区三区| 国产精品午夜国产小视频| av成人老司机| 亚洲欧美日韩人成在线播放| 欧美日韩精品二区| 99精品视频免费观看视频| 在线亚洲欧美| 国产精品v片在线观看不卡 | 欧美视频免费看| 一卡二卡3卡四卡高清精品视频| 在线综合欧美| 国产精品乱码久久久久久| 亚洲午夜免费视频| 久久精品1区| 激情综合电影网| 免费不卡在线观看| 亚洲欧洲午夜| 亚洲欧美日韩视频一区| 国产视频在线观看一区| 久久精品国产96久久久香蕉| 欧美激情精品久久久久久大尺度 | 玖玖在线精品| 亚洲激情第一页| 欧美午夜电影一区| 午夜精品www| 欧美~级网站不卡| 日韩一区二区精品在线观看| 国产精品jizz在线观看美国| 亚洲欧美日韩在线| 欧美国产日韩在线观看| 在线一区免费观看| 国产精品一区二区三区久久久| 久久久久久综合网天天| 亚洲欧洲日韩综合二区| 午夜视频一区二区| 亚洲精品极品| 国产精品免费一区二区三区观看| 欧美在线视频导航| 亚洲欧洲另类国产综合| 久久激情综合| 在线亚洲精品| 在线日本成人| 国产精品免费网站| 欧美黄色日本| 久久精品99国产精品| 99综合精品| 欧美国产日韩在线观看| 欧美在线视频a| 亚洲免费精品| 精品成人一区二区三区| 国产精品99免费看| 美女性感视频久久久| 亚洲欧美激情在线视频| 亚洲麻豆国产自偷在线| 久久综合激情| 久久精品视频在线| 亚洲午夜精品一区二区| 亚洲大黄网站| 韩国v欧美v日本v亚洲v| 国产精品久久久久久久久| 欧美成人午夜影院| 久久久久久高潮国产精品视| 亚洲夜晚福利在线观看| 亚洲日韩中文字幕在线播放| 另类国产ts人妖高潮视频| 亚洲欧美一区二区在线观看| 亚洲美女在线一区| 亚洲国产日韩欧美在线动漫| 国产一区二区三区四区老人| 国产精品高清一区二区三区| 欧美国产精品一区| 免费亚洲电影| 美女视频一区免费观看| 久久久久久9| 久久久久久久91| 久久国产精品久久久久久久久久| 亚洲无亚洲人成网站77777| 亚洲精品一区二区在线观看| 亚洲国产精品va在线看黑人动漫 | 国产伦精品一区二区三区在线观看 | 久久综合99re88久久爱| 欧美一区观看| 久久精品综合一区| 久久久久久色| 久久婷婷激情| 免费在线欧美黄色| 牛牛影视久久网| 亚洲第一福利在线观看| 亚洲电影在线| 亚洲欧洲在线一区| 亚洲人成欧美中文字幕| 亚洲精品裸体| 亚洲图片在区色| 欧美一区永久视频免费观看| 欧美亚洲三区| 久久精品国产第一区二区三区最新章节 | 亚洲精品久久嫩草网站秘色| 亚洲美女av黄| 亚洲图片欧美一区| 性欧美暴力猛交另类hd| 久久久久国产精品一区三寸| 美女国产精品| 欧美日韩一区二区国产| 国产精品视频在线观看| 国产一区二区三区黄| 在线观看中文字幕亚洲| 亚洲精品一二三| 亚洲自拍三区| 久久影视精品| 亚洲精品免费一二三区| 亚洲视频网在线直播| 欧美一区二区三区四区高清| 久久免费精品视频| 欧美日韩情趣电影| 国产视频久久久久| 亚洲国产午夜| 亚洲欧美成人在线| 久久中文字幕一区| 亚洲蜜桃精久久久久久久| 亚洲欧美日韩国产中文| 久热国产精品| 国产精品福利在线| 亚洲国产日韩欧美在线99| 亚洲综合清纯丝袜自拍| 美女黄网久久| 亚洲午夜激情| 嫩模写真一区二区三区三州| 国产精品免费久久久久久| 亚洲高清av| 欧美一区视频在线| 最新国产成人在线观看| 欧美一级专区| 欧美色综合天天久久综合精品| 国内精品视频久久| 亚洲综合视频一区| 欧美激情欧美狂野欧美精品| 亚洲专区一二三| 欧美韩日一区二区| 尤物99国产成人精品视频| 午夜亚洲影视| 日韩视频在线播放| 久久综合伊人| 国模精品一区二区三区色天香| 国产精品99久久99久久久二8 | 一本色道久久综合亚洲精品不 | 欧美一级网站| 日韩亚洲在线观看| 久久久另类综合| 国产日韩欧美日韩大片| 在线一区二区日韩| 亚洲黄页视频免费观看| 久久久久国内| 激情久久久久久久久久久久久久久久| 亚洲伊人色欲综合网| 亚洲精品美女91| 欧美成人一区二区三区在线观看| 国产一区在线免费观看| 久久爱www久久做| 午夜精品久久久久| 国产精品乱码久久久久久| 亚洲午夜精品17c| 日韩午夜三级在线| 欧美日韩视频不卡| 亚洲午夜精品国产| 中文精品视频| 国产精品国产三级国产a| aⅴ色国产欧美| 日韩系列在线| 欧美图区在线视频| 亚洲影院污污.| 亚洲一区二区三区免费视频| 国产精品福利片| 久久精品国产99国产精品| 欧美亚洲系列| 原创国产精品91| 亚洲国产三级网|