C++ C++;在函数中声明的结构在main中可见

C++ C++;在函数中声明的结构在main中可见,c++,c++14,C++,C++14,为什么这个代码可以工作?使用c++14 // Example program #include <iostream> #include <string> using namespace std; auto fun() { struct a { int num = 10; a() { cout << "a made\n"; } ~a()

为什么这个代码可以工作?使用
c++14

// Example program
#include <iostream>
#include <string>
using namespace std;


auto fun()
{
    struct a
    {
        int num = 10;
        a()
        {

            cout << "a made\n";
        }
        ~a()
        {
            cout << "a destroyed\n";
        }
    };
    static a a_obj;
    return a_obj;
}


int main()
{
    auto x = fun();
    cout << x.num << endl;

}
//示例程序
#包括
#包括
使用名称空间std;
汽车娱乐()
{
结构a
{
int num=10;
()
{

coutC++14对
auto
越来越宽容。您的问题不清楚,因为您没有说明问题所在

现在让我们以不同的方式来解决您的问题:为什么它不能与
ax=…
一起工作

原因是结构定义不在main的范围内。现在可以这样做:

// Example program
#include <iostream>
#include <string>
using namespace std;

struct a
{
    int num = 10;
};

auto fun()
{
    static a a_obj;
    return a_obj;
}


int main()
{
    a x = fun();
    cout << x.num << endl;

}
//示例程序
#包括
#包括
使用名称空间std;
结构a
{
int num=10;
};
汽车娱乐()
{
静态a_obj;
返回一个_obj;
}
int main()
{
a x=乐趣();

cout在你意识到这一点之前,这一切都是令人惊讶的:名称可见性并没有隐藏类型。它只是隐藏类型的名称。一旦你理解了这一点,一切都是有意义的

我可以不使用
auto
,只使用普通的旧模板向您展示:

auto fun()
{
    struct Hidden { int a; };

    return Hidden{24};
}

template <class T> auto fun2(T param)
{
    cout << param.a << endl; // OK
} 

auto test()
{
    fun2(fun()); // OK
}
auto-fun()
{
结构隐藏{int a;};
返回隐藏的{24};
}
模板自动fun2(T参数)
{

因为
fun
的返回类型被推断为
struct a
,它难道不知道吗?如果我从
auto x=
更改为
a x=
它不编译,为什么让
auto
工作呢?因为编译器会在编译时推断返回的变量,所以他知道它将是
struct a
。如果使用
a x=
,编译器不知道此数据类型,因为它在另一个作用域中声明。因为您无法直接访问
a
。您可以使用
decltype(fun())x;
来表示
fun
返回的任何类型的“make
x
”。不是将x.num称为编译器错误,实现细节不应该在fun()之外可见(您使用的是哪种编译器)我知道您的代码工作的原因,我只是在测试函数中的结构时看到一些东西,但是
auto
可以“猜测”这一事实让我有点害怕:(@pyjg“guess”是错误的词。它要么毫无疑问地知道,要么给你一个错误。没有猜测。@pyjg实际上对我来说更奇怪的是它在C++98/03中无法检测到它。为什么不呢?在决定类型时绝对没有歧义,那么为什么要创建编译错误呢?这就是在C++14中引入这种灵活性的原理。@nwp“Detect”听起来更好?我相信合适的术语是“Detection”,就像在模板参数推断中一样。在C++03中,甚至可以通过类返回私有类型的实例来完成同样的事情。另一个例子是lambdas,它从来没有名称,但通常只是带有
运算符()
的结构。