【问题标题】:C++ - Forward declaration and alias (with using or typedef)C++ - 前向声明和别名(使用 using 或 typedef)
【发布时间】:2013-09-16 18:17:42
【问题描述】:

我需要实现如下接口

struct mutex;
struct interface
{
  //...
  mutex& getMutex();
};

直觉上我可以在我的实现中使用using mutex = ParticularMutex,但 gcc 告诉我不然:

error: conflicting declaration ‘using mutex = ’
error: ‘class mutex’ has a previous declaration as ‘class mutex’

我没有定义两次,只是声明两次,像往常一样向前声明,所以

  1. 为什么这不起作用?
  2. 有没有不修改interface的解决方法?
  3. 应该如何定义interfacetemplate <typename mutex>?

【问题讨论】:

    标签: c++ templates alias using forward-declaration


    【解决方案1】:
    1. 它不起作用,因为前向声明 struct mutex; 告诉编译器 mutex 是一种新类型。使用using,您将创建一个类型alias,这意味着它不是new 类型(正如编译器所承诺的那样),而是现有类型的别名。

    2. 没有。

    3. 是的。


    可以做的是:

    struct mutex : ParticularMutex {
        using ParticularMutex::ParticularMutex; // inherit constructors
    };
    

    它确实定义了从ParticularMutex 派生的类型,希望它足够兼容。当然,这是一种新类型,可能会导致其他问题。

    【讨论】:

    • 不过,我不明白为什么编译器应该关心。我想知道为什么没有办法转发声明“此名称代表 some 类型。您现在不需要知道确切的定义,但您将在链接时拥有它”
    • @ricab 编译器很关心,因为这是标准所要求的。它是否有用或者是否应该有某种方式来前向声明类型别名是另一个问题。坦率地说,模板参数就是这样:它告诉interface,您稍后将提供某种类型(或类型别名)。
    • @ricab 我用一个可能的解决方案更新了答案,检查它是否适合你。
    • 是的,我想知道标准不包含更通用的 fwd 声明机制的原因是什么。使用 typedef 定义 mutex 时,我没有看到语义上的相关变化
    • 另外,您的解决方案也有效。您必须将答案修改为 2. 从“否”到“是”:) 顺便说一句,值得注意的是,gcc4.7 不支持 using 构造函数(我必须使用一个在线编译器来确认它)
    【解决方案2】:

    在类似的情况下(使用 JNI 抽象),这是我所做的:

    JNI 无法识别的文件 MyObject.h

    class PlatformObject; // forward declaration
    struct MyObject {
            int accumulator;
            PlatformObject* platformObj;
    };
    

    JNI 感知文件 jniBridge.cpp

    #include <jni.h>
    #define PlatformObject _jobject
    #include "MyObject.h"
    
    void attach(MyObject& obj, jobject parent) {
        obj.platformObj = env->GetObjectField(parent, child_FieldID);
    }
    
    void add(MyObject& obj, int k) {
        accumulator += k;
        env->CallVoidMethod(obj.platformObj, add_MethodID, k);
    }
    

    accepted answer 适用于 add() 但不适用于 attach();后者需要额外的 static_cast

    我相信在某些情况下,这两种方法都有其优势。

    【讨论】:

      【解决方案3】:
      • 首先你说mutex 是一个特定的类类型。然后你说“哦等等,mutex 不是它自己的类型,它真的是 这个其他类型”。在这种情况下编译器不知道该怎么做。

      • 用 using 替换 struct mutext,它应该可以正常工作(我不完全了解 C++11 的使用情况)。

      • 如果您希望能够支持多个互斥锁实现,您可能希望将接口设为模板(或使用互斥抽象接口,虚拟决定调用哪个互斥锁实现)。

        李>

      【讨论】:

      • 谢谢,关于 2:我可能不够明确,但我的意思是“是否有不修改 file 其中interface 前向声明在吗?”
      【解决方案4】:

      嗯,您通常可以通过将 ParticularMutex 的存根声明添加到您的一个标头来解决此问题。比如:

      namespace foreignlib {
          namespace foreignsublib {
              class ParticularMutex;
          }
      }
      

      然后在您的一般标题中:

      namespace ourlib {
          using mutex = foreignlib::foreignsublib::ParticularMutex;
      }
      

      这工作正常,解析和编译速度很快。优势:阅读您的一般标题的人都知道,您的特定 mutex 到底代表什么。缺点:您不能编写与互斥量无关的库,稍后您可以使用using 指令放入一个或另一个互斥量。如果您想要或需要这样做,C++ 之神希望您改用模板。但这些都是有代价的......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 2011-03-02
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多