gpt4 book ai didi

c++ - 在不同的命名空间中调用别名声明的基类构造函数

转载 作者:太空宇宙 更新时间:2023-11-04 14:10:59 25 4
gpt4 key购买 nike

我试图通过 C++11 的 using 了解别名声明类的一些细节,以及这如何/为什么影响基类构造函数调用。

示例代码

#include <iostream>

namespace N {

template<typename T>
struct Foo
{
// Foo(){}; // NOTE: If this line is present, error 2 goes away.
Foo(T t):value(t){};
~Foo() = default;
T value;
};

struct BarInt : public Foo<int>
{
BarInt(int t):Foo< int >(t){};
~BarInt() = default;
};

using BarFloat = Foo<float>;

};

struct A : public N::BarInt
{
A(int i=42):BarInt(i){}; //BarInt(i) or N::BarInt(i) doesn't matter here
~A() = default;
};

struct B : public N::BarFloat
{
B(float f=23.0):BarFloat(f){}; //two errors with gcc4.7.2 (with -std=gnu++11)

// B(float f=23.1):N::BarFloat(f){}; //this line seems to work.
~B() = default;
};


int main(int argc, char **argv)
{
A a;
B b;
std::cout << "a's value is "<< a.value << "\n"
<< "b's value is "<< b.value << std::endl;
return 0;
}

gcc 4.7.2(使用 -std=gnu++11 编译)为此代码生成了两个错误,我认为它们是相关的(尽管我不明白如何...)

错误 1

main.cpp: In constructor ‘B::B(float)’:
main.cpp:32:19: error: class ‘B’ does not have any field named ‘BarFloat’

我在 stackoverflow 上的搜索显示了 Is a namespace required when referring to the base class ,其中提到注入(inject)的类名作为进一步搜索的起点。然而,根据我收集到的信息,这解释了为什么我可以按照我的方式为 A 编写构造函数(即 A(int i=42):BarInt(i){}; ) 以及为什么 BarInt(i) 不必使用命名空间 N 进行限定。

那么为什么它不适用于 B?根据What is the difference between 'typedef' and 'using' in C++11? , using 与一个很好的旧 typedef 相同,所以我想我对第一个错误的问题是别名声明类(BarFloat 在我的示例)在注入(inject)类名的上下文中不同于常规类(在我的示例中为 BarInt)。非常感谢任何指针:)

错误2

main.cpp:32:29: error: no matching function for call to ‘N::Foo<double>::Foo()’
main.cpp:32:29: note: candidates are:
main.cpp:9:5: note: N::Foo<T>::Foo(T) [with T = double]
main.cpp:9:5: note: candidate expects 1 argument, 0 provided
main.cpp:6:10: note: constexpr N::Foo<double>::Foo(const N::Foo<double>&)
main.cpp:6:10: note: candidate expects 1 argument, 0 provided

如上例代码中所述,如果我引入一个空的 Foo() 构造函数,此错误就会消失。然而,我的问题是,为什么 BarFloat(f) 会触发对空 Foo() 构造函数的调用,在这种情况下,BarFloat.value 如何触发 可能会设置为 23.0。

后脚本

因为这是我在这里发表的第一篇文章:你好 stackoverflow,感谢大家通过帮助他人解决问题为我提供的巨大帮助!

最佳答案

当您从一个类继承时,派生类可以无限制地访问基类的名称(包括基类名称本身)。您实际上是在继承基类中的名称。这就是为什么从 N::BarInt 继承的原因允许您引用 BarIntA 内没有资格。

对于 B ,您继承自 Foo<double>使用 BarFloat 别名,但是 Foo<double>不包含 BarFloat ,因此您不会继承该名称。

第二个错误只是因为第一个失败。由于编译器没有看到基的有效初始化,就像您根本没有显式初始化基一样,所以它被迫使用您没有的默认构造函数对其进行初始化。

关于c++ - 在不同的命名空间中调用别名声明的基类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14363338/

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