猿问

派生模板-对基类成员的类访问-数据

派生模板-对基类成员的类访问-数据

这个问题是本文所提问题的进一步。这条线.

使用以下类定义:

template <class T>class Foo {public:
    Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)
    {
        /* do something for foo */
    }
    T Foo_T;        // either a TypeA or a TypeB - TBD
    foo_arg_t _foo_arg;};template <class T>class Bar : public Foo<T> {public:
    Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo<T>(bar_arg)   // base-class initializer
    {

        Foo<T>::Foo_T = T(a_arg);
    }

    Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo<T>(bar_arg)
    {
        Foo<T>::Foo_T = T(b_arg);
    }

    void BarFunc ();};template <class T>void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl;   // This doesn't work - compiler error is: error: ‘_foo_arg’ was not declared in this scope
    std::cout << Bar<T>::_foo_arg << std::endl;   // This works!}

在访问模板类的基类成员时,似乎必须始终使用模板样式语法对成员进行显式限定。Bar<T>::_foo_arg..有办法避免这种情况吗?“使用”语句/指令能否在模板类方法中发挥作用以简化代码?

编辑:

通过使用以下->语法对变量进行限定来解决范围问题。


烙印99
浏览 533回答 3
3回答

米脂

在Visualc+2008中工作得很好。我为您提到的类型添加了一些虚拟定义,但没有给出源代码。其余的和你说的完全一样。然后主要作用是BarFunc实例化和调用。#include&nbsp;<iostream>class&nbsp;streamable&nbsp;{};std::ostream&nbsp;&operator<<(std::ostream&nbsp;&os,&nbsp;streamable&nbsp;&s)&nbsp;{&nbsp;return&nbsp;os;&nbsp;}class&nbsp;foo_arg_t&nbsp;:&nbsp; public&nbsp;streamable&nbsp;{};class&nbsp;a_arg_t&nbsp;:&nbsp;public&nbsp;streamable&nbsp;{};class&nbsp;b_arg_t&nbsp;:&nbsp;public&nbsp;streamable&nbsp;&nbsp;{};template&nbsp;<class&nbsp;T>class&nbsp;Foo&nbsp;{public: &nbsp;&nbsp;&nbsp;&nbsp;Foo&nbsp;(const&nbsp;foo_arg_t&nbsp;foo_arg)&nbsp;:&nbsp;_foo_arg(foo_arg) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;do&nbsp;something&nbsp;for&nbsp;foo&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;Foo_T;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;either&nbsp;a&nbsp;TypeA&nbsp;or&nbsp;a&nbsp;TypeB&nbsp;-&nbsp;TBD &nbsp;&nbsp;&nbsp;&nbsp;foo_arg_t&nbsp;_foo_arg;};template&nbsp;<class&nbsp;T>class&nbsp;Bar&nbsp;:&nbsp;public&nbsp;Foo<T>&nbsp;{public: &nbsp;&nbsp;&nbsp;&nbsp;Bar&nbsp;(const&nbsp;foo_arg_t&nbsp;bar_arg,&nbsp;const&nbsp;a_arg_t&nbsp;a_arg) &nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;Foo<T>(bar_arg)&nbsp;&nbsp;&nbsp;//&nbsp;base-class&nbsp;initializer &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foo<T>::Foo_T&nbsp;=&nbsp;T(a_arg); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;Bar&nbsp;(const&nbsp;foo_arg_t&nbsp;bar_arg,&nbsp;const&nbsp;b_arg_t&nbsp;b_arg) &nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;Foo<T>(bar_arg) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foo<T>::Foo_T&nbsp;=&nbsp;T(b_arg); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;BarFunc&nbsp;();};template&nbsp;<class&nbsp;T>void&nbsp;Bar<T>::BarFunc&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;_foo_arg&nbsp;<<&nbsp;std::endl;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;Bar<T>::_foo_arg&nbsp;<<&nbsp;std::endl;&nbsp;&nbsp;&nbsp;}int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;Bar<a_arg_t>&nbsp;*b&nbsp;=&nbsp;new&nbsp;Bar<a_arg_t>(foo_arg_t(),&nbsp;a_arg_t()); &nbsp;&nbsp;&nbsp;&nbsp;b->BarFunc();}

炎炎设计

在这里,基类不是一个非依赖的基类(这意味着一个具有可以在不知道模板参数的情况下确定的完整类型的基类),并且_foo_arg是一个非依赖的名称。标准C+说,在依赖基类中不查找非依赖的名称。若要更正代码,只需创建名称即可。_foo_arg依赖的原因是,只有在实例化时才能查找依赖的名称,并且在那个时候,必须探索的确切的基本专门化将被知道。例如://&nbsp;solution#1std::cout&nbsp;<<&nbsp;this->_foo_arg&nbsp;<<&nbsp;std::endl;另一种方法是使用限定名引入依赖项://&nbsp;solution#2std::cout&nbsp;<<&nbsp;Foo<T>::_foo_arg&nbsp;<<&nbsp;std::endl;必须注意此解决方案,因为如果使用不限定的非依赖名称来形成虚拟函数调用,则限定会抑制虚拟调用机制,程序的含义也会发生变化。之后,您可以从派生类中的依赖基类中带一个名称。using://&nbsp;solution#3template&nbsp;<class&nbsp;T>class&nbsp;Bar&nbsp;:&nbsp;public&nbsp;Foo<T>&nbsp;{public: &nbsp;&nbsp;&nbsp;&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;BarFunc&nbsp;();private: &nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;Foo<T>::_foo_arg;};template&nbsp;<class&nbsp;T>void&nbsp;Bar<T>::BarFunc&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;_foo_arg&nbsp;<<&nbsp;std::endl;&nbsp;&nbsp;&nbsp;//&nbsp;works}
随时随地看视频慕课网APP
我要回答