C ++ - 前向声明和别名(使用using或typedef)

时间:2013-09-16 18:17:43

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

我需要实现以下界面

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. 应如何定义interface?与template <typename mutex>

4 个答案:

答案 0 :(得分:6)

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

  2. 没有


  3. 可以做的是:

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

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

答案 1 :(得分:1)

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

JNI-unaware文件 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适用于添加(),但适用于 attach();后者需要额外的 static_cast

我认为在某些情况下,这两种方法都有其优点。

答案 2 :(得分:0)

  • 首先,您说mutex是特定的类类型。然后你会说“哦等等,mutex不是它自己的类型,它实际上是这个其他类型”。在这种情况下,编译器不知道该怎么做。

  • struct mutext替换为使用,它应该可以正常工作(我在使用C ++ 11时并不完全是最新的。)

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

答案 3 :(得分:0)

好吧,您通常可以通过将 ParticularMutex 的存根声明添加到您的标头之一来解决此问题。类似的东西:

namespace foreignlib {
    namespace foreignsublib {
        class ParticularMutex;
    }
}

然后在您的通用标题中:

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

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