Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-转发声明和别名(使用或typedef)_C++_Templates_Alias_Using_Forward Declaration - Fatal编程技术网

C++ C++;-转发声明和别名(使用或typedef)

C++ C++;-转发声明和别名(使用或typedef),c++,templates,alias,using,forward-declaration,C++,Templates,Alias,Using,Forward Declaration,我需要实现以下接口 struct mutex; struct interface { //... mutex& getMutex(); }; 直觉告诉我,我可以在我的实现中使用使用mutex=specialmutex,但gcc告诉我另外一种情况: error: conflicting declaration ‘using mutex = ’ error: ‘class mutex’ has a previous declaration as ‘class mutex’ 我并没

我需要实现以下接口

struct mutex;
struct interface
{
  //...
  mutex& getMutex();
};
直觉告诉我,我可以在我的实现中使用
使用mutex=specialmutex
,但gcc告诉我另外一种情况:

error: conflicting declaration ‘using mutex = ’
error: ‘class mutex’ has a previous declaration as ‘class mutex’
我并没有定义任何东西两次,只是声明了两次,就像在向前声明时一样,所以

  • 为什么这样不行
  • 是否有不修改
    界面
    的变通方法
  • 如何定义
    接口
    ?使用
    模板
    • 首先,您要说的是,
      mutex
      是一种特定的类类型。然后你会说“哦,等等,
      mutex
      不是它自己的类型,它实际上是另一种类型”。编译器不知道在这种情况下该怎么办

    • 用using替换
      struct mutext
      ,它应该可以正常工作(我并没有完全更新C++11的using)

    • 如果您希望能够支持多个互斥体实现,您可能希望将该接口设置为模板(或者使用一个互斥体抽象接口,该接口实际上决定调用哪个互斥体实现)

  • 它不起作用,因为前向声明
    struct mutex
    告诉编译器
    互斥体是一种新类型。使用
    时,您将创建一个类型别名,这意味着它不是一个新类型(正如向编译器承诺的那样),而是一个现有类型的别名

  • 没有


  • 你能做的是:

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

    在类似的情况下(使用JNI抽象),下面是我的工作:

    JNI文件MyObject.h

    class PlatformObject; // forward declaration
    struct MyObject {
            int accumulator;
            PlatformObject* platformObj;
    };
    
    #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);
    }
    
    JNI感知文件jniBridge.cpp

    class PlatformObject; // forward declaration
    struct MyObject {
            int accumulator;
            PlatformObject* platformObj;
    };
    
    #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);
    }
    
    #包括
    #定义平台对象_作业对象
    #包括“MyObject.h”
    无效附加(MyObject和obj、jobject父对象){
    obj.platformObj=env->GetObjectField(父、子\u字段ID);
    }
    无效添加(MyObject和obj,int k){
    累加器+=k;
    env->CallVoidMethod(obj.platformObj,add_MethodID,k);
    }
    
    该选项适用于添加(),但不适用于附加();后者需要额外的静态施法


    我认为,在某些情况下,两种方法都有各自的优势

    通常,您可以通过将该
    SpecialMutex
    的存根声明添加到一个头中来解决这个问题。比如:

    namespace foreignlib {
        namespace foreignsublib {
            class ParticularMutex;
        }
    }
    
    然后在您的常规标题中:

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

    这很好,解析和编译速度很快。优点:无论谁读了您的通用头,都知道您的特定
    mutex
    到底代表什么。缺点:您无法编写互斥体不可知库,以后可以使用
    using
    指令插入一个或另一个互斥体。如果你想要或者需要这样做,C++神想让你使用模板来代替。但是这些都是有代价的…

    谢谢,关于2:我可能不够明确,但我的意思是“在不修改
    接口
    和转发声明所在的文件的情况下,是否有一个变通方法?”尽管如此,我不明白编译器为什么要在意。我想知道为什么没有一种向前声明的方法说“这个名称代表某种类型。你现在不需要知道确切的定义,但你会在链接时知道它”@ricab编译器关心它,因为这是标准要求的。它是否有用,或者是否应该有某种方法向前声明类型别名,则是另一个问题。坦白地说,模板参数就是这样的:它告诉
    接口
    ,稍后您将提供某种类型(或类型别名)。@ricab我用一个可能的解决方案更新了答案,检查它是否对您有效。是的,我想知道标准不包括更通用的fwd声明机制的原因是什么。当使用typedefAlso定义
    互斥体时,我看不到语义上有任何相关的变化,因此,您的解决方案是有效的。您必须将答案修改为2。从“否”到“是”:(顺便说一句,值得注意的是,gcc4.7不支持以这种方式使用构造函数(我必须使用在线编译器来确认)