c++ - 命名空间中函数特化的 undefined reference

标签 c++ templates namespaces g++ undefined-reference

我正在实现一个以 boost::archive 为模型的 JSON 归档系统.对于您想要序列化的每种类型,您定义一个非侵入式函数来接受文件和您的对象:

// archive.hpp
#pragma once

namespace Archive {
    template <class A, class T>
    void serialize(A& a, T& value);
}

struct ArchiveOut {
    void add(const char* key, int& value) {}

    // ... Implementations for basic types ...

    template <class T>
    void add(const char* key, T& value) {
        ArchiveOut archive;
        Archive::serialize(archive, value);
    }
};
// main.cpp
#include "archive.hpp"

struct Child {
    int id;
};

struct Parent {
    int id;
    Child child;
};

template <class A>
void Archive::serialize(A& a, Parent& v) {
    a.add("id", v.id);
    a.add("child", v.child);
}

template <class A>
void Archive::serialize(A& a, Child& v) {
    a.add("id", v.id);
}

int main() {
    Parent parent;
    ArchiveOut archive;
    Archive::serialize(archive, parent);
}
现在,该系统适用于复杂的嵌套类型,但仅适用于 serialize位于全局命名空间中。一旦它移入 Archive命名空间我收到链接器错误:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\DDP\AppData\Local\Temp\ccMWEvEu.o:test.cpp:(.text$_ZN10ArchiveOut3addI5ChildEEvPKcRT_[_ZN10ArchiveOut3addI5ChildEEvPKcRT_]+0x20): undefined reference to `void Archive::serialize<ArchiveOut, Child>(ArchiveOut&, Child&)
我知道我的专业有正确的签名,因为它们匹配 boost 的,但也许我的初始原型(prototype)是错误的?我试过挖掘 boost 内部,但找不到初始 serialize 的位置原型(prototype)是。我还检查了其他答案,所有答案都与不匹配函数签名或未将其放置在正确命名空间中的特化有关。我能得到这个链接器行为的解释吗?

最佳答案

您在需要部分特化的地方使用重载。
问题是一个函数不能被部分特化。
建议:在部分专用结构中使用静态函数。
如下(注意:代码未测试)

// archive.hpp

namespace Archive {
    template <typename A, typename T>
    struct serial;

    template <class A, class T>
    void serialize(A& a, T& value)
     { serial<A, T>::func(a, value); }
}

// main.cpp
#include "archive.hpp"

// ...

namespace Archive {

   template <class A>
   struct serial<A, Parent>
    {
      static void func (A & a, Parent & v)
       {
         a.add("id", v.id);
         a.add("child", v.child);
       }
    };  

   template <class A>   
   struct serial<A, Child>
    {
      static void func (A & a, Child & v)
       { a.add("id", v.id); }
    };
 }

关于c++ - 命名空间中函数特化的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66947142/

相关文章:

c++ - boost notify_all 上的进程间条件阻塞

mysql - 在Golang网站中使用模板显示mysql表

C++::#include:ing 多个源文件中的模板类头文件?

java - play2 framework 我的模板没见过。 : package views. html不存在

c++ - 何时在 C++ 中使用 Pimpl 模式而不是嵌套类,反之亦然?

c++ - C++ 标准 11 实现的 std::move 函数

android - 跨平台(C++/Android)无损/低噪声视频压缩/解压库

无法通过 spl_autoload_register 加载具有命名空间的 PHP 类?

asp.net - 在类库中添加 System.Web.Script 引用

C# 命名空间结构迫使我使用别名