【问题标题】:Is it possible to use anonymous classes in C++?是否可以在 C++ 中使用匿名类?
【发布时间】:2017-10-25 16:54:27
【问题描述】:

我在 Quora 上的 C++ 代码中看到了匿名类。它已成功编译并运行。

代码在这里:

#include <iostream>

auto func()
{
    class // no name
    {
      public:
             int val;
    } a;

    a.val = 5;

    return a;
}

int main()
{
    std::cout << func().val << std::endl;
    return 0;
}

那么,它在 C++ 中有效吗?

另外,我很想知道,是否可以在 C++ 中使用匿名类?

【问题讨论】:

  • 有点像asked before
  • C++ 有anonymous unions,但没有匿名类/结构,一些编译器将其作为扩展提供。尽管如此,问题中显示的未命名类仍然有效。
  • @cpplearner an anonymius union 是一个没有名称(成员,而不是类型)的联合类型的类 member
  • @n.m 通常是一个“匿名”类/联合意味着既没有名称,也没有实例化的对象。它的成员成为封闭类范围或函数块范围的成员。一个未命名的类仅仅意味着没有名字,但除此之外它是一个带有立即声明对象的普通类。 C++ 没有匿名类,只有匿名联合。
  • @JohannesSchaub-litb 我刚刚在标准中查找了它,它说匿名联合是联合的一种特殊形式,它定义了一个未命名类型的未命名对象。假设它只能是另一个类的成员,我错了。

标签: c++ class c++11 g++ c++14


【解决方案1】:

不仅如此,您还可以使用decltype创建更多的类实例。

#include <iostream>

class 
{
   public:
      int val;
} a;


int main()
{
   decltype(a) b;
   a.val = 10;
   b.val = 20;

   std::cout << a.val << std::endl;
   std::cout << b.val << std::endl;
   return 0;
}

输出:

10
20

【讨论】:

  • 在 C++11 之前真的没有办法声明一个未命名类的另一个实例吗?
  • @lisyarus:可以使用template &lt;typename T&gt; T create(const T&amp; prototype) { return T(); }这样的模板
  • @AlexandreC。但是,如果我无权访问该类型(create 之外),如何将create 的结果分配给局部变量?
  • 我认为在 C++11 之前这是不可能的,因为您无法将此类对象传递给模板(类型必须具有外部链接)。不过我可能记错了。上面在命名空间范围内声明a 的代码在C++03 中格式错误,因为具有链接的对象(a 具有外部链接)需要具有链接的类型,但该类型没有链接。我相信 C++11 在这里改变了规则,但我再次不确定。
  • @lisyarus 这就是所谓的移动球门柱! template&lt;typename T&gt; void create(const T&amp; prototype) { T t; } 创建一个与匿名类型匹配的局部变量。
【解决方案2】:

在 C++ 中,匿名联合是这种形式的联合:

 union { ... } ;

它定义了一个未命名类型的未命名对象。它的成员被注入到周围的作用域中,因此可以在不使用 &lt;object&gt;. 前缀的情况下引用它们,否则这是必要的。

从这个意义上说,不存在匿名类(不是联合 --- 在 C++ 中联合是类)。

另一方面,未命名的类(包括结构和联合)并不罕见。

union { ... } x;
class { ... } y;
typedef struct { ... } z;

xy 是未命名类型的命名对象。 z 是一个 typedef-name,它是未命名结构的别名。它们不被称为匿名,因为这个术语是为上述联合形式保留的。

[](){}

Lambda 是未命名类类型的未命名对象,但它们也不称为匿名。

【讨论】:

  • 不是std::function类型的lambdas吗?
  • @DonaldDuck 不,它们可以转换为 std::function 但每个 lambda 都有自己独特的类型。
  • @DonaldDuck 不,他们有一个实现定义的类型。 std::function 使用类型擦除绑定到任何可以像函数一样调用的类/函数,即函数对象,例如 lambda。
【解决方案3】:

总是可以这样写:

typedef struct { int a; } type;

现在,如果您查看struct { int a } 部分,这是一个匿名结构。在 C++ 中,结构和类之间基本上没有区别(默认访问修饰符除外)。因此,可以有匿名结构/类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    相关资源
    最近更新 更多