У нас есть заголовочный файл, который содержит некоторые остатки для различных значений точности с плавающей запятой:
template <typename T>
struct rsdTarget {
static const double value;
};
template <>
const double rsdTarget<half>::value = (double)(1.0e-3);
template <>
const double rsdTarget<float>::value = (double)(1.0e-7);
template <>
const double rsdTarget<double>::value = (double)(1.0e-12);
Это сработало, потому что этот заголовок был включен только в одну единицу компиляции. Теперь я пытаюсь использовать этот заголовок в нескольких модулях компиляции и получаю ошибки компоновщика, связанные с ODR:
CMakeFiles/tests_g.dir/random_gauge.cc.o:(.rodata+0x108): multiple definition of `rsdTarget<double>::value'
CMakeFiles/tests_g.dir/clover_product.cc.o:(.rodata+0x548): first defined here
Инициализация, вероятно, должна войти в исходный файл и быть извлечена из файла заголовка. Однако кажется, что extern
перед const double
запрещено.
Что мне нужно сделать, чтобы это работало с несколькими единицами компиляции?
Обновлять
Я думал, что решение этой проблемы для double
полностью исправит ситуацию. Однако есть второй небуквенный тип, который я также должен выполнить:
template <typename T>
struct tolerance {
static const QDP::Double small; // Always fail
};
template <>
const QDP::Double tolerance<half>::small = QDP::Double(5.0e-3);
template <>
const QDP::Double tolerance<float>::small = QDP::Double(1.0e-6);
template <>
const QDP::Double tolerance<double>::small = QDP::Double(1.0e-7);
Кажется, я не могу использовать это с constexpr
, потому что этот тип его не поддерживает (требуется constexpr
ctor, верно?). Какое из решений работает и с этим?
inline
в специализации. (И рассмотрите возможность замены этого встроенной переменной, если вы используете современный компилятор) - person M.M   schedule 20.07.2017__declspec(selectany)
перед специализацией шаблона для компилятора Microsoft. - person ikleschenkov   schedule 20.07.2017