объявленная extern специализированная функция не найдена - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь реализовать клон библиотеки сериализации json nlohmann :: json для обучения, и у меня возникают проблемы с интерфейсом для преобразования, определенного пользователем (json <-> Тип пользователя).

По сути, я хочу, чтобы пользователь мог перегрузить две функции: to_json (json &, const Type &) и from_json (const json &, Type &). Затем библиотека будет использовать разрешение перегрузки для вызова этой функции в шаблонном operator = и конструкторе с одним аргументом.

Это прекрасно работает, когда я просто определяю тезисную функцию напрямую, но когда я пытаюсь сделать определение шаблона для нескольких типов (в этом примере класса S), компоновщик не может найти определение.

Я пытался явно создать экземпляр функции для отдельных экземпляров шаблонного класса, хотя я бы предпочел избегать этого в конечном продукте.

Я предполагаю, что это связано с тем фактом, что шаблонная функция не имеет той же сигнатуры, что и свободная функция, но я не понимаю, что я могу сделать, чтобы заставить ее работать. Что мне не хватает? Я также не смог найти результат в Google, так что это задокументированный шаблон или анти-шаблон?

Спасибо тебе. Ниже я попытался минимизировать свою проблему в одном коротком примере.

Class.hpp

#pragma once
#include <cstdio>

template<size_t i>
class S {
    size_t n = i;
};

template<size_t i>
void g(const S<i>& s) {
    printf("S<%u>\n", i);
}

Class.cpp

#include "Class.hpp"

template void g<10>(const S<10>&); // <-- Even with explicitly instanciation

void g(const bool& b) {
    printf("%s\n", b ? "true" : "false");
}

main.cpp

#include "Class.hpp"

template<typename T>
void f(T t) {
    extern void g(const T&);
    g(t);
}

int main(int, char**) {
    S<10> s;
    //f(s); <-- linker error: void g(class S<10> const &) not found.
    f(false);
}

1 Ответ

0 голосов
/ 13 ноября 2018

Поиск имени для g в g(t) вызове прекращается, как только он находит extern void g(const T&); объявление; он никогда не видит объявление шаблона функции. Таким образом, компилятор генерирует вызов обычной не шаблонной функции с именем g, принимая const S<10>&. Но такая функция не определена в вашей программе - следовательно, ошибка компоновщика.

...