Ошибка компоновщика при использовании класса шаблона со ссылочным нетиповым параметром шаблона - PullRequest
0 голосов
/ 09 января 2019

Я занимаюсь разработкой библиотеки C ++, в которой мне нужно предоставить шаблон класса пользователю.

Параметр шаблона этого класса является справочным. Однако я получаю ошибку компоновщика. Вот минимальный тестовый пример:

test.hh

#ifndef TEST_HH_
#define TEST_HH_

template <double const& val>
struct A{};

constexpr double zero = 0.;

A<zero> foo();

#endif // TEST_HH_

test.cpp

#include "test.hh"

A<zero> foo(){ return A<zero>(); }

main.cpp

#include "test.hh"

int main()
{
    foo();
}

При компиляции этого фрагмента кода я получаю предупреждение:

'A<zero> foo()' used but never defined

с последующей ошибкой компоновщика:

undefined reference to foo()

Я пытался заменить double на int:

template <int val>
struct A{};

и он связан (при передаче int в качестве параметра ofc), но мне действительно нужен double.

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

1 Ответ

0 голосов
/ 09 января 2019

Будь счастлив, что это не ссылка! Могло быть и хуже ...

Проблема в основном в том, что test.cpp и main.cpp оба имеют разные объекты с именем ::zero. Это нарушение ODR - у вас есть несколько определений для этой переменной, и в результате вы получите A<zero>, технически являющийся разными типами, поскольку параметр шаблона A val является ссылкой на разные объекты в разных единицах перевода.

Надеюсь, это объяснение прояснит, почему A<int> работает нормально.

В C ++ 17 вы хотите:

inline constexpr double zero = 0.;

В C ++ 14 вам нужно либо добавить определение в одну из единиц перевода, либо заняться каким-либо другим видом магии, например, если ::zero сам по себе будет ссылкой на некоторую статическую переменную шаблона или другую вуду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...