C++ 什么';在C+中,类型和名称之间的区别是什么+;?
我正在阅读,我在这个问题的代码中添加了一个构造函数,如下所示C++ 什么';在C+中,类型和名称之间的区别是什么+;?,c++,c++11,types,C++,C++11,Types,我正在阅读,我在这个问题的代码中添加了一个构造函数,如下所示 class Foo { struct Bar { int i; Bar(int a = 5) :i(a) {}; }; public: Bar Baz() { return Bar(); } }; int main() { Foo f; // Foo::Bar b = f.Baz(); // error auto b = f.Baz();
class Foo {
struct Bar {
int i;
Bar(int a = 5) :i(a) {};
};
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout <<"b.i="<< b.i<<endl;
return 0;
}
typedef条B
在Foo
的公共部分,以下内容之间有什么区别
Foo::Bar b = f.Baz();
Foo::B b = f.Baz();
public
和private
关键字与名称相关,而与基础类型或成员无关
为了显式声明特定类型的对象,您需要该类型的名称<代码>自动不需要这个。例如,如果使用未命名的类,则该类没有名称,但仍可在其上使用auto
一个类型最多只能有一个“”。即使通过typedef或别名使用它,编译器也会在这个名称下使用它(或者实际上是这个名称的原始版本)。因此:
如果不使用auto或decltype,就无法创建变量f
。因为它的类型没有名字。没有名称的类型的另一个示例
struct foo
{
struct{
int x;
int y;
} memberVar;
};
将允许您执行以下操作:
foo bar;
auto baz = bar.memberVar;
std::cout << baz.x;
打印“int”
注意事项:
- 我避免使用alias作为对象其他名称的指示符,因为这可能会导致与alias关键字混淆
- 这大部分是我从经验中得到的。所以我可能错过了一些片段
- 由于缺少一个更好的词,我用了“真名”这个词。如果有人知道官方的说法或更好的说法,我很乐意听到:)
autob=…
中,您让编译器推断表达式的类型。无法指定类型,因为类型的名称已隐藏。但类型是可用的(至少从编译器)auto
演绎的工作方式与模板参数演绎的工作方式相同:
[dcl.spec.auto]/p7
如果占位符是自动
类型说明符,使用模板参数推断规则确定推断的类型
模板在编译过程中会受到影响。在第一阶段,访问控制应用于名称查找
[basic.lookup]/p1
重载解析(13.3)在名称查找成功后进行。只有在名称查找和函数重载解析(如果适用)成功后,才会考虑访问规则(第11条)。只有在名称查找、函数重载解析(如果适用)和访问检查成功后,才能在表达式处理中进一步使用名称声明引入的属性
auto
和decltype(auto)
通常是推断类型的占位符,[temp.arg]/p3确实表示
模板参数的名称应可在用作模板参数的位置访问
但是这里不涉及名称,只涉及类型。访问控制适用于名称,一个类型可以映射为0、1或多个名称,这就是在上面的代码中使用auto
时要处理的问题:它在语义上等同于模板推断的语义,这是经过设计的
[class.access]/p4
访问控制统一应用于所有名称,无论这些名称是从声明中引用的还是从
表达。[……]无障碍
不考虑typedef所指实体的名称。比如说
为了让自己相信以下内容,请看一看包含模板参数推断的相同代码(概念上等同于auto
version)
模板
T推断(T){
返回t;
}
福班{
结构条{
int i;
Bar(inta=5):i(a){};
};
公众:
Bar*getB(){返回新的Bar(5);}//泄漏,为了清晰起见并不重要
};
int main(){
福福;
std::我可以说没有私有类型。只有私有成员,这只意味着它们的名称是不可访问的。类型本身不受访问控制。dyp是对的,名称和类型是两个不同的东西,在编译过程中处理方式不同phases@laurisvr,你能给我一个前男友吗这个类型的例子中没有命名的联盟吗?是这个例子中的未命名的联盟吗?是<代码> int >代码>被认为是<代码> int <代码>的类型吗?@ @ ALANQUUNZI我已经编辑了我的帖子以包含一些例子。并且进一步阐述了命名的工作原理。请注意C++禁止在返回或参数中定义新的类型。类型,如中所述。但是,还有其他一些方法可以创建返回未命名类型的函数。(我将在几分钟内添加其中一些。)@dyp“有些编译器适用于int为16位的体系结构。”你是对的。我的遗漏很愚蠢。我已经相应地更新了答案。
auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } ;
struct foo
{
struct{
int x;
int y;
} memberVar;
};
foo bar;
auto baz = bar.memberVar;
std::cout << baz.x;
std::cout << typeid(int32_t).name();
class A {
class B { };
public:
typedef B BB;
};
void f() {
A::BB x; // OK, typedef name A::BB is public
A::B y; // access error, A::B is private
}
template<class T>
T deduce(T t) {
return t;
}
class Foo {
struct Bar{
int i;
Bar(int a = 5):i(a){};
};
public:
Bar *getB() { return new Bar(5); } // Leaks, doesn't matter for clarity's sake
};
int main() {
Foo f;
std::cout <<"b.i="<< deduce(f.getB())->i <<std::endl; // Prints 'b.i=5'
return 0;
}