在派生类初始化器列表中初始化模板基类类成员类型 [英] Initializing template base-class member types in derived-class initializer lists

查看:145
本文介绍了在派生类初始化器列表中初始化模板基类类成员类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一些代码概述了我一直在摔跤的问题。最后的问题(就目前的g ++而言)是:执行Bar :: Bar(...)构造函数时,错误:'Foo-T'没有在这个范围内声明。否则,我试图学习我的方法的问题之一是基于使用模板传递给派生类构造函数的参数设置基类成员类型。如果有一种方法设置基类成员类型(T Foo-T)简单地通过传递参数到派生类构造函数,我更喜欢。到目前为止,我不能看到一个过去使用模板参数和匹配的派生类构造函数参数来完成这个任务。你能发现下面的代码中的任何东西,我可以做得更好,实现相同的目标吗?我对通用编码和模板很新。

Here is some code outlining a problem I've been wrestling with. The final problem (as far as g++ is concerned at the moment) is that: "error: 'Foo-T' was not declared in this scope" when performing the Bar::Bar(...) constructor routine. Otherwise, the problem I'm attempting to learn my way through is one of setting base-class member types based on arguments passed to a derived-class constructor using templates. If there were a way to set the base-class member type (T Foo-T) simply by passing arguments to the derived-class constructor, I would prefer that. As of now I can't see a way past using both the template argument and a matching derived-class constructor argument to accomplish this task. Can you spot anything in the following code that I can be doing better to achieve the same goals? I'm rather new to generic-coding and templates.

#include <iostream>
typedef int a_arg_t;
typedef double b_arg_t;
typedef std::string foo_arg_t;

class TypeA {
public:
    TypeA ();
    TypeA (a_arg_t a) {
        /* Do sosmething with the parameter passed in */
    }

};

class TypeB {
public:
    TypeB ();
    TypeB (b_arg_t b) {
        /* typeB's constructor - do something here */
    }

};

// The base-class with a member-type to be determined by the template argument
template <class T>
class Foo {

public:
    Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)       // initialize something here
    {
        /* do something for foo */
    }
    T Foo_T;        // either a TypeA or a TypeB - TBD
    foo_arg_t _foo_arg;
};

// the derived class that should set the basse-member type (T Foo_T)
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
    {
        // the initialization of Foo_T has to be done outside the initializer list because it's not in scsope until here
        Foo_T = TypeA(a_arg);   // if an a_arg_t is passed in, then we set the Foo_T to TypeA, etc.
    }

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

};

int main () {

    b_arg_t b_arg;
    a_arg_t a_arg;
    foo_arg_t bar_arg;

    Bar<TypeA> a (bar_arg, a_arg);  // try creating the derived class using TypeA
    Bar<TypeB> b (bar_arg, b_arg); // and another type for show

return 0;
}


推荐答案

Foo_T类型不会

Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
: Foo<T>(bar_arg)   // base-class initializer
{
    Foo_T = TypeA(a_arg);   TypeA, etc. // Won't compile, per the standard
}

根据C ++标准,其中不合格的名称通常是非依赖的,并且应该在模板完全定义时查找。

This is per the C++ standard, which says unqualified names are generally non-dependent, and should be looked up when the template is fully defined.

由于模板基类定义在当时是未知的(在编译单元的后面可能会有完全专用的模板实例),非限定名称

Since a template base class definition is not known at that time (there could be fully specialised instances of the template being pulled in later in the compilation unit), unqualified names are never resolved to names in dependent base classes.

如果在涉及模板时需要基类的名称,则必须完全限定它们,或者隐式地使用它们依赖于您的派生类。

If you need a name from a base class when templates are involved, you have to either fully qualify them, or make them implicitly dependent in your derived class.

 Foo< T >::Foo_T = TypeA(a_arg);   // fully qualified will compile

或使其依赖

 this->Foo_T = TypeA(a_arg);

由于解析类型被推迟到模板实例化的阶段2(然后,基类也是完全已知的)

Since the this makes it template dependent, resolving the type is postponed till "phase 2" of template instantiation (and then, the base class is also fully known)

注意,如果你想使用一个函数基本类,你也可以添加一个使用声明..

Note that if you wanted to use a function from the base class, you could have also added a using declaration..

(在Bar()内部)

  some_foo_func(); // wouldn't work either

  using Foo<T>::some_foo_func;
  some_foo_func(); // would work however

这篇关于在派生类初始化器列表中初始化模板基类类成员类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆