Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++ 在不同命名空间中调用别名声明的基类构造函数_C++_C++11_Constructor_Base Class_Using Declaration - Fatal编程技术网

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

C++ 在不同命名空间中调用别名声明的基类构造函数,c++,c++11,constructor,base-class,using-declaration,C++,C++11,Constructor,Base Class,Using Declaration,我试图通过C++11的使用了解alias声明类的一些细节,以及这如何/为什么会影响基类构造函数调用 示例代码 我在stackoverflow上的搜索提到了注入的类名作为进一步搜索的起点。然而,从我收集的资料来看,这解释了为什么我可以按照我的方式为A编写构造函数(即作为A(inti=42):BarInt(I){};),以及为什么BarInt(I)不必使用名称空间N进行限定 那么为什么这对B不起作用呢?根据,使用与旧的类型定义是一样的,因此我想第一个错误的问题是,在注入类名的上下文中,alias声明

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

示例代码 我在stackoverflow上的搜索提到了注入的类名作为进一步搜索的起点。然而,从我收集的资料来看,这解释了为什么我可以按照我的方式为
A
编写构造函数(即作为
A(inti=42):BarInt(I){};
),以及为什么
BarInt(I)
不必使用名称空间
N
进行限定

那么为什么这对
B
不起作用呢?根据,
使用
与旧的
类型定义
是一样的,因此我想第一个错误的问题是,在注入类名的上下文中,alias声明的类(
BarFloat
)与常规类(
BarInt
)有何不同。非常感谢您的指点:)

错误2
main.cpp:32:29:错误:调用'N::Foo::Foo()'时没有匹配的函数
main.cpp:32:29:注:候选人为:
main.cpp:9:5:note:N::Foo::Foo(T)[带T=double]
main.cpp:9:5:注意:候选者需要1个参数,提供0个参数
main.cpp:6:10:注意:constexpr N::Foo::Foo(const N::Foo&)
main.cpp:6:10:注意:候选者需要1个参数,提供0个参数
如果如上面示例代码中所述,我引入了一个空的
Foo()
构造函数,那么这个错误就会消失。然而,我的问题是为什么
BarFloat(f)
触发对空
Foo()
构造函数的调用,在这种情况下,
BarFloat.value
如何可能设置为23.0

后脚本
因为这是我在这里的第一篇帖子:你好,stackoverflow,感谢你们通过帮助他人解决问题而为我提供的巨大帮助

从类继承时,派生类可以无条件地访问基类的名称(包括基类名称本身)。您实际上是在继承基类中的名称。这就是为什么继承自
N::BarInt
允许您无条件地引用
A
中的
BarInt

对于
B
,您使用BarFloat别名从
Foo
继承,但
Foo
不包含
BarFloat
,因此您不会继承该名称


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

当您从类继承时,派生类可以访问基类的名称(包括基类名称本身)没有限定。您有效地继承了基类中的名称。这就是为什么从
N::BarInt
继承允许您在
A
中引用
BarInt
而没有限定的原因

对于
B
,您使用BarFloat别名从
Foo
继承,但
Foo
不包含
BarFloat
,因此您不会继承该名称


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

感谢您的快速回答,尽管我有一些后续的问题问题:对于错误1,您有效地解释了为什么它适用于
BarInt
,但是您知道为什么它不适用于
BarFloat
?对于错误2,缺少的空构造函数:如果编译器找不到基(
BarFloat
)由于缺少名称空间,它如何知道基的基,即
Foo
?@hcc23:第二段描述了为什么它不适用于BarFloat。不过,在您第一次看到我的答案后,我可能已经补充了这一点。啊,感谢第二段(我在键入第一条评论时一定错过了),这对我来说似乎很有意义。@hcc23:编译器主要从上到下处理文本。当您声明
B
时,您指定它的基为
N::BarFloat
,这很好,因为它是合格的。此时,类的其余部分现在可以看到
Foo
的内容。编译器只是无法看到
BarFloat
,因为它不在
Foo
中。感谢您的快速回答,尽管我确实有一些后续问题:对于错误1,您有效地解释了为什么它适用于
BarInt
,但是您知道为什么它不适用于
BarFloat
?对于错误2,缺少的空构造函数:如果由于缺少名称空间,ompiler找不到基(
BarFloat
),它如何知道基的基,即
Foo
?@hcc23:第二段描述了为什么它不适用于BarFloat。不过,在您第一次看到我的答案后,我可能已经添加了这一点。啊,感谢第二段(在键入第一条评论时,我一定错过了),这对我来说似乎很有意义。@hcc23:编译器主要从上到下处理文本。当您声明
B
时,您指定它的基为
N::BarFloat
,这很好,因为它是合格的。此时,类的其余部分现在可以看到
Foo
的内容。编译器只是无法查看
BarFloat
,因为它不在
Foo
中。
#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;
}
main.cpp: In constructor ‘B::B(float)’:
main.cpp:32:19: error: class ‘B’ does not have any field named ‘BarFloat’
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