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

大龍的博客

常用鏈接

統計

最新評論

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

很少用模板類,今天用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 大龍 閱讀(2402) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲一区二区三区精品视频| 亚洲国产精品久久久久| 欧美日韩国产另类不卡| 在线欧美不卡| 毛片av中文字幕一区二区| 国产精品v欧美精品∨日韩| 亚洲国内精品在线| 亚洲在线观看视频网站| av成人免费在线观看| 欧美日韩久久精品| 亚洲综合导航| 中文精品视频一区二区在线观看| 欧美日韩高清在线一区| 亚洲天堂成人在线观看| 99视频精品全部免费在线| 欧美精品少妇一区二区三区| 一本大道久久精品懂色aⅴ| 亚洲精品一区二区三区樱花| 久久久久亚洲综合| 亚洲精品乱码久久久久久日本蜜臀| 欧美va亚洲va国产综合| 欧美激情综合五月色丁香小说| 亚洲精品久久久一区二区三区| 亚洲人成网站在线观看播放| 欧美精品999| 香蕉久久国产| aa国产精品| av成人黄色| 国产亚洲精品综合一区91| 蜜臀av一级做a爰片久久| 免费在线一区二区| 性欧美1819性猛交| 久久久免费观看视频| 亚洲精品国产精品国自产观看浪潮| 日韩视频一区二区三区在线播放免费观看 | 伊人狠狠色丁香综合尤物| aa国产精品| 亚洲欧洲精品一区二区三区波多野1战4 | 香蕉尹人综合在线观看| 中文在线资源观看网站视频免费不卡 | 午夜国产精品影院在线观看| 在线看无码的免费网站| 亚洲综合日韩在线| 日韩视频一区二区三区在线播放免费观看 | 欧美一级黄色录像| 欧美日韩一区在线播放| 欧美黄免费看| 怡红院精品视频在线观看极品| 亚洲一区一卡| 亚洲一级黄色片| 欧美激情片在线观看| 久久综合电影| 国产午夜精品久久久久久免费视| 日韩午夜电影| 99视频精品| 欧美精品久久一区| 亚洲欧洲一区| 亚洲激情欧美激情| 久久久久久久久伊人| 久久婷婷麻豆| 激情懂色av一区av二区av| 亚洲欧美国产不卡| 久久se精品一区精品二区| 国产精品一区免费观看| 午夜精品在线| 久久青草久久| 精品动漫3d一区二区三区免费| 久久精品国产一区二区三区免费看| 久久国产乱子精品免费女| 国产日韩在线不卡| 久久久精品一区| 亚洲电影免费观看高清完整版| 伊人春色精品| 欧美国产三区| 99精品视频免费全部在线| 亚洲欧美国产制服动漫| 久久精品国产精品亚洲精品| 国产精自产拍久久久久久| 欧美亚洲午夜视频在线观看| 久久精品一区二区三区四区| 激情五月婷婷综合| 模特精品在线| 99伊人成综合| 久久久噜噜噜久久人人看| 亚洲第一精品夜夜躁人人爽| 欧美二区在线播放| 在线中文字幕日韩| 久久色在线播放| 亚洲免费av网站| 国产精品一区二区男女羞羞无遮挡 | 日韩网站在线观看| 欧美一区二区免费| 国产一区二区三区在线观看视频 | 性久久久久久久| 麻豆成人小视频| 这里只有精品丝袜| 国产一区二区黄| 欧美人与性动交α欧美精品济南到| 亚洲精品欧美激情| 久久国产精品网站| 日韩视频久久| 国产欧美精品一区二区三区介绍| 久久成人久久爱| 一区二区三区四区国产精品| 久久亚洲国产成人| 亚洲天堂网在线观看| 永久久久久久| 国产精品乱看| 欧美国产三区| 午夜在线a亚洲v天堂网2018| 欧美激情一区二区| 久久国产精品亚洲77777| 夜夜嗨av一区二区三区四季av| 国产精品久久久久久久电影 | 亚洲视频二区| 欧美大片在线看| 久久九九久精品国产免费直播| 亚洲人体影院| 在线观看成人一级片| 国产精品毛片va一区二区三区| 欧美不卡在线视频| 久久久久成人精品免费播放动漫| 亚洲最新中文字幕| 亚洲国产精品专区久久| 久久久久久久久久久久久女国产乱 | 欧美日本一区二区视频在线观看| 久久久久久尹人网香蕉| 香蕉尹人综合在线观看| 夜夜嗨一区二区三区| 亚洲日本aⅴ片在线观看香蕉| 欧美成人久久| 美日韩精品视频免费看| 久久久久久久97| 久久久精品日韩欧美| 欧美一区二区三区另类| 亚洲小视频在线| 亚洲免费一区二区| 亚洲一区制服诱惑| 亚洲综合视频1区| 亚洲综合不卡| 亚洲欧美中文在线视频| 亚洲欧美在线aaa| 亚洲欧美一区二区三区极速播放| 一区二区三区四区五区精品视频| 亚洲人成网站777色婷婷| 亚洲乱码视频| 亚洲色图综合久久| 亚洲欧美日韩国产一区二区三区| 亚洲专区欧美专区| 欧美在线观看视频在线 | 正在播放欧美一区| 亚洲天堂av电影| 欧美一区二区三区视频免费播放| 午夜精品久久久久久99热软件| 欧美在线播放一区| 久久这里有精品15一区二区三区| 免费不卡在线观看av| 亚洲国产精品传媒在线观看| 亚洲精品视频在线观看免费| 日韩一级欧洲| 亚洲欧美一区二区在线观看| 久久riav二区三区| 女女同性女同一区二区三区91| 欧美欧美天天天天操| 国产精品毛片a∨一区二区三区| 国产亚洲精品自拍| 亚洲人成网站777色婷婷| 亚洲一级片在线观看| 久久久国产精品一区二区中文| 欧美黑人在线观看| 一本色道久久综合| 午夜视频在线观看一区二区| 久久午夜精品| 欧美性感一类影片在线播放| 国产曰批免费观看久久久| 1769国产精品| 亚洲欧美日韩国产精品| 免费成人在线视频网站| 99国产精品久久久久久久久久| 欧美中文字幕精品| 欧美日韩在线播放| 尤物99国产成人精品视频| 亚洲一区二区高清| 蜜桃av一区二区| 亚洲欧美国产77777| 欧美二区在线播放| 激情一区二区三区| 亚洲女爱视频在线| 亚洲国产精品久久人人爱蜜臀| 亚洲一区精彩视频| 欧美日韩国产专区| 亚洲国产黄色片| 久久久久久一区二区三区| 亚洲免费精品| 久久天堂精品| 国产日韩欧美中文| 亚洲欧美视频在线观看视频| 亚洲高清久久网| 久久精品国产99| 国产欧美一区二区视频|