Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问模板基类';派生类的构造函数 请考虑以下情况: 1) 参数化基类A 2) 从A派生的参数化派生类B_C++ - Fatal编程技术网

C++ 访问模板基类';派生类的构造函数 请考虑以下情况: 1) 参数化基类A 2) 从A派生的参数化派生类B

C++ 访问模板基类';派生类的构造函数 请考虑以下情况: 1) 参数化基类A 2) 从A派生的参数化派生类B,c++,C++,当派生类的ctor尝试引用基类时,会发生编译错误: /** Examines how to invoke the Base class ctor from the Derived class, when both classes are templates. */ #include <iostream> using namespace std; template<typename T> class A ///

当派生类的ctor尝试引用基类时,会发生编译错误:

/** Examines how to invoke the Base class ctor
    from the Derived class,
    when both classes are templates.
*/

#include <iostream>

using namespace std;


template<typename T>
class A                     /// base class
{
public:
    A(int i)
    {
    }
};


template<typename T>
class B : public A<T>         /// derived class
{
public:
    B(int i) :
        A {i}
    {
    }
};


int main()
{
    A<int> a {5};
    B<int> b {10};
}
/**检查如何调用基类
从派生类中,
当两个类都是模板时。
*/
#包括
使用名称空间std;
模板
类A///基类
{
公众:
A(国际一)
{
}
};
模板
类B:公共A///派生类
{
公众:
B(国际一级):
A{i}
{
}
};
int main()
{
A A{5};
B{10};
}

错误:

\main.cpp||In constructor 'B<T>::B(int)':|
\main.cpp|26|error: class 'B<T>' does not have any field named 'A'|

\main.cpp||In instantiation of 'B<T>::B(int) [with T = int]':|
\main.cpp|35|required from here|
\main.cpp|26|error: no matching function for call to 'A<int>::A()'|

\main.cpp|26|note: candidates are:|
\main.cpp|15|note: A<T>::A(int) [with T = int]|
\main.cpp|15|note:   candidate expects 1 argument, 0 provided|
\main.cpp|12|note: constexpr A<int>::A(const A<int>&)|
\main.cpp|12|note:   candidate expects 1 argument, 0 provided|
\main.cpp|12|note: constexpr A<int>::A(A<int>&&)|
\main.cpp|12|note:   candidate expects 1 argument, 0 provided|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
\main.cpp | |在构造函数“B::B(int)”中:|
\main.cpp | 26 |错误:类“B”没有任何名为“A”的字段|
\main.cpp | |在“B::B(int)[带T=int]的]的实例化中:|
\main.cpp | 35 |从这里开始需要|
\main.cpp | 26 |错误:调用“A::A()”时没有匹配的函数|
\main.cpp | 26 |注:候选人包括:|
\main.cpp | 15 |注:A::A(int)[带T=int]|
\main.cpp | 15 |注:候选者需要1个参数,提供0个参数|
\main.cpp | 12 |注:常量表达式A::A(常量A&)|
\main.cpp | 12 |注:候选者需要1个参数,提供0个参数|
\main.cpp | 12 |注:constepr A::A(A&&)|
\main.cpp | 12 |注:候选者需要1个参数,提供0个参数|
||==生成失败:2个错误,2个警告(0分钟,0秒))===|

编译器将B类的ctor解释为初始化B类中的字段a,而不是调用a类的ctor


如何解决这一问题?

注入的类名将仅在该类中工作,而不是在派生类中工作,因此请将代码更改为以下内容:

#include <iostream>

using namespace std;


template<typename T>
class A                     /// base class
{
public:
    A(int i)
    {
    }
};


template<typename T>
class B : public A<T>         /// derived class
{
public:
    B(int i) :
        A<T> {i} // added <T>
    {
    }
};


int main()
{
    A<int> a {5};
    B<int> b {10};
}
#包括
使用名称空间std;
模板
类A///基类
{
公众:
A(国际一)
{
}
};
模板
类B:公共A///派生类
{
公众:
B(国际一级):
添加了{i}//
{
}
};
int main()
{
A A{5};
B{10};
}

基类的名称在
B
的构造函数中使用时是一个依赖名称,因为它所指的内容取决于模板参数
T
。看

名称查找规则不同。如果名称依赖于当前范围(
T
)的模板参数,则名称在当前范围(即
B
的构造函数)中不可用

在这种情况下,需要在
B
中指定整个全名:

template<typename T>
class B : public A<T>         /// derived class
{
public:
    B(int i) :
        A<T> {i}
    {
    }
};
那么基类的模板参数只需要在代码中重复一次。

您应该在
B(int i)行中使用
A
而不是
A
:A{i}
使用base=A习惯用法在模板参数列表很长且多次使用的实际用例中非常有用。它避免了重复并使代码维护更容易,因为如果某些内容发生更改,您只需更改一次(干式原则)。
template<typename T>
class B : public A<T>
{
public:
    void f()
    {
        A<T>::g();  // defined in A
    }
};
class B : public A<T>         /// derived class
{
    using base = A<T>;
public:
    B(int i) :
        base {i}
    {
    }
};