这个问题是对以下问题的进一步推进 这个线程.

使用以下类定义:

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. 。有办法避免这种情况吗?“using”语句/指令可以在模板类方法中发挥作用来简化代码吗?

编辑:

通过使用 this-> 语法限定变量来解决范围问题。

有帮助吗?

解决方案

您可以使用this->作出清楚,你指的是类的成员:

void Bar<T>::BarFunc () {
    std::cout << this->_foo_arg << std::endl;
}

可替换地也可以在该方法中使用的 “using”:

void Bar<T>::BarFunc () {
    using Bar<T>::_foo_arg;             // Might not work in g++, IIRC
    std::cout << _foo_arg << std::endl;
}

这使得它清楚的成员名称取决于模板参数,使其搜索在正确的地方,这个名字的定义编译器。欲了解更多信息,见在C ++ FAQ精简版此项。

其他提示

下面的基类不是一个非依赖基类(这意味着一个具有能够在不知道模板参数来确定一个完整的类型),以及_foo_arg是一个非依赖名称。标准C ++表示,非依赖名称没有在从属基类查找。

要纠正代码,它足以使名称_foo_arg依赖性,因为相关的名称只能在实例化时进行查找,在那个时候,必须探索确切基地专业化将是已知的。例如:

// solution#1
std::cout << this->_foo_arg << std::endl;

一种替代包括使用限定名引入的依赖关系:

// solution#2
std::cout << Foo<T>::_foo_arg << std::endl;

必须注意用这种溶液,因为,如果不合格非依赖名称用于形成虚拟函数调用,则资格抑制虚拟调用机制和的程序变化的含义。

和可以从从属基类派生类通过using带来名称一次:

// solution#3
template <class T>
class Bar : public Foo<T> {
public:
    ...
    void BarFunc ();
private:
    using Foo<T>::_foo_arg;
};

template <class T>
void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl;   // works
}

出现在Visual C ++ 2008以做工精细,我增加了一些假的定义,你提到的类型,但没有透露来源。剩下的就是完全按照你所说的那样。然后被实例化以迫使BarFunc一个主要功能和调用。

#include <iostream>

class streamable {};
std::ostream &operator<<(std::ostream &os, streamable &s) { return os; }

class foo_arg_t : public streamable {};
class a_arg_t : public streamable {};
class b_arg_t : public streamable  {};

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; 
    std::cout << Bar<T>::_foo_arg << std::endl;   
}

int main()
{
    Bar<a_arg_t> *b = new Bar<a_arg_t>(foo_arg_t(), a_arg_t());
    b->BarFunc();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top