gpt4 book ai didi

c++ - 在派生类初始化器列表中初始化模板基类成员类型

转载 作者:IT老高 更新时间:2023-10-28 22:37:22 25 4
gpt4 key购买 nike

这里有一些代码概述了我一直在努力解决的问题。最后一个问题(目前就 g++ 而言)是:执行 Bar::Bar(...) 构造函数例程时,“错误:'Foo-T' 未在此范围内声明”。否则,我试图解决的问题是基于使用模板传递给派生类构造函数的参数设置基类成员类型之一。如果有一种方法可以简单地通过将参数传递给派生类构造函数来设置基类成员类型(T Foo-T),我更愿意这样做。到目前为止,我看不到同时使用模板参数和匹配的派生类构造函数参数来完成此任务的方法。您能在以下代码中发现我可以做得更好以实现相同目标的任何内容吗?我对通用编码和模板比较陌生。

#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) 构造函数中使用时不会在基类中查找。

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++ 标准,它说非限定名称通常是不依赖的,并且应该在完全定义模板时查找。

由于当时不知道模板基类定义(在编译单元的后面可能有模板的完全专用实例被拉入),因此非限定名称永远不会解析为依赖基类中的名称。

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

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

或者,让它依赖

 this->Foo_T = TypeA(a_arg);

由于 this 使其依赖于模板,因此解析类型被推迟到模板实例化的“阶段 2”(然后,基类也完全已知)

请注意,如果您想使用基类中的函数,您还可以添加 using 声明..

(在 Bar() 内)

  some_foo_func(); // wouldn't work either

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

关于c++ - 在派生类初始化器列表中初始化模板基类成员类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1117693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com