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

大龍的博客

常用鏈接

統計

最新評論

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

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

比如

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就會報錯,B類的foo函數中m_a找不到。

解決辦法是 B類的foo函數這么寫

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

或者

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

原因請看這段話:

//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.
//


原理是名字查找的規則問題。由于還要加班調程序,下次再寫名字查找的原理

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


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   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>
            亚洲视频大全| 亚洲小视频在线观看| 久久电影一区| 午夜在线a亚洲v天堂网2018| 欧美理论在线| 久久免费99精品久久久久久| 国产夜色精品一区二区av| 先锋影音久久久| 亚洲自拍偷拍一区| 激情伊人五月天久久综合| 一区二区激情| 亚洲视频第一页| 欧美福利视频| 亚洲午夜精品一区二区| 亚洲一区图片| 精品福利免费观看| 91久久在线播放| 欧美在线亚洲综合一区| 久久精品观看| 亚洲精品极品| 香蕉久久国产| 亚洲片在线观看| 亚洲午夜一区二区三区| 国产自产在线视频一区| 欧美高清在线一区| 国产精品免费一区二区三区观看| 久久精品女人的天堂av| 欧美精品黄色| 欧美主播一区二区三区美女 久久精品人| 久久久久久成人| 中国av一区| 久久久爽爽爽美女图片| 亚洲视频一二| 久久久一区二区| 性视频1819p久久| 欧美成人嫩草网站| 久久精品一区四区| 欧美色一级片| 欧美二区不卡| 91久久精品视频| 国产欧美一区二区视频| 亚洲精品一级| 亚洲高清不卡在线| 羞羞答答国产精品www一本| 一本色道久久88综合日韩精品| 午夜国产欧美理论在线播放 | 妖精视频成人观看www| 国产最新精品精品你懂的| 亚洲美女av在线播放| 1000部精品久久久久久久久| 亚洲综合国产| 亚洲一区二区三区成人在线视频精品| 久久久噜噜噜久久狠狠50岁| 欧美一级艳片视频免费观看| 欧美日韩国产在线看| 欧美大秀在线观看| 尤妮丝一区二区裸体视频| 午夜欧美理论片| 亚洲欧美另类国产| 欧美日韩亚洲高清| 亚洲激情视频在线| 亚洲国产精品va在看黑人| 久久高清福利视频| 久久久久国色av免费看影院 | 欧美精品一区二区久久婷婷| 久久青草福利网站| 国产精品一区二区视频| 亚洲婷婷免费| 欧美一区二区三区另类| 国产精品久久久一本精品| 亚洲破处大片| 一区二区三区精品在线| 欧美日韩精品久久| av成人手机在线| 亚洲一区欧美激情| 国产精品久久久久久一区二区三区| 亚洲另类在线一区| 亚洲伊人一本大道中文字幕| 欧美日韩久久久久久| 一本久久青青| 午夜免费日韩视频| 狠狠入ady亚洲精品| 久久夜色撩人精品| 亚洲第一黄色| 亚洲视频一区二区| 国产精品久久一级| 欧美一区二区视频在线观看2020| 久久精品视频va| 尤物在线观看一区| 欧美成人免费全部| 亚洲网站在线观看| 久久久一二三| 亚洲精品综合在线| 国产精品网站一区| 久久久www成人免费毛片麻豆| 欧美成人精品高清在线播放| av成人免费观看| 国产乱肥老妇国产一区二| 久久久久成人精品免费播放动漫| 欧美激情第8页| 亚洲欧美日韩国产成人| 一区二区视频欧美| 欧美日韩国产精品专区| 亚洲欧美中文另类| 亚洲成在人线av| 国产亚洲永久域名| 男人的天堂成人在线| 一区二区三区精品| 欧美国产精品专区| 午夜精品久久久久| 亚洲精品日韩精品| 国内视频精品| 国产精品mv在线观看| 久久综合给合久久狠狠狠97色69| 夜夜嗨av一区二区三区中文字幕| 久久综合久久美利坚合众国| 中日韩午夜理伦电影免费| 在线精品国产成人综合| 国产精品久久久一区麻豆最新章节 | 亚洲精品网站在线播放gif| 国产欧美日本一区二区三区| 欧美国产日韩在线观看| 欧美在线电影| 亚洲免费一在线| 亚洲剧情一区二区| 欧美韩国在线| 美女亚洲精品| 久久久www成人免费精品| 亚洲午夜高清视频| 最新成人av在线| 亚洲电影在线免费观看| 激情欧美国产欧美| 国产欧美日韩视频一区二区| 欧美日韩色一区| 欧美精品大片| 欧美激情久久久久| 欧美韩日精品| 欧美激情成人在线视频| 欧美成人午夜激情| 毛片精品免费在线观看| 久久久精品日韩欧美| 久久国产精品高清| 久久精品99久久香蕉国产色戒| 亚洲一区二区三区中文字幕| 99国内精品久久久久久久软件| 亚洲国产欧美一区二区三区丁香婷| 麻豆精品一区二区综合av | 99在线热播精品免费| 亚洲国产天堂久久综合| 亚洲国产高清自拍| 亚洲国产岛国毛片在线| 亚洲黄色成人| 一区二区高清在线| 亚洲一区二区影院| 欧美夜福利tv在线| 久久久久久一区二区| 久久中文精品| 欧美二区在线播放| 亚洲精品一区二区三区福利| 亚洲免费av观看| 亚洲综合激情| 久久久久五月天| 免费一区视频| 欧美日韩综合视频网址| 国产精品九九久久久久久久| 国产精品一区亚洲| 韩国一区二区三区美女美女秀| 亚洲第一搞黄网站| 一区二区三区高清在线| 午夜精品久久久久久久久久久久久 | 国产亚洲毛片| 亚洲第一中文字幕| 99视频精品在线| 午夜伦欧美伦电影理论片| 蜜臀久久99精品久久久画质超高清| 欧美成人亚洲| 亚洲视频第一页| 久久这里只有精品视频首页| 欧美日韩国产va另类| 国产视频久久| 日韩视频中文字幕| 欧美一区国产一区| 亚洲国产精品国自产拍av秋霞| 99精品国产在热久久婷婷| 久久成人免费视频| 欧美美女日韩| 精品成人国产在线观看男人呻吟| 99热这里只有成人精品国产| 久久久www成人免费无遮挡大片 | 久久久水蜜桃| 亚洲毛片在线看| 久久精品欧美| 欧美性片在线观看| 在线观看视频一区二区| 午夜精品福利视频| 亚洲高清视频中文字幕| 欧美在线观看视频一区二区三区| 欧美国产亚洲视频| 有坂深雪在线一区| 久久久久成人精品|