Определенный шаблонный метод inline не найден для специализации

Рассмотрим следующий минимальный пример:

template <int A> struct Foo {
    inline Foo();
};
template <> struct Foo<1> {
    inline Foo();
};

template <int A>
inline Foo<A>::Foo() {}

int main() {
    Foo<2> okay;
    Foo<1> fail; //<- Compile warn/error here!  Why?
}

Как видите, я определяю struct Foo и сделать полную специализацию этого. Затем я определяю метод интерьера.

Когда я строю okay это вызывает Foo<2>::Foo(), принимая определение, которое я дал. Тем не менее, когда я пытаюсь построить fail, он пытается позвонить Foo<1>::Foo(), и это не работает (печатает предупреждение компиляции, ссылка не работает). Почему это происходит?


Выходы различных компиляторов, для вашего удобства:
• GCC 7.2.0: предупреждение: встроенная функция "Foo<1>::Foo()" используется, но не определена
• Clang 5.0.0: предупреждение: встроенная функция 'Foo<1>::Foo' не определена [-Wundefined-inline]
• ICC 17 [работает счастливо]
• MSVC 2017 [работает счастливо]

1 ответ

Решение

Почему это происходит?

Потому что вы не определили это. Полная специализация шаблона класса, по сути, приводит к "обычному" определению класса. Вы можете добавлять, опускать или изменять членов класса.

Это также означает, что он ничего не получает от основного шаблона "автоматически". Вы должны предоставить это явно. И так как вы не предоставили

inline Foo<1>::Foo() {} // Note how we don't need template<> here? Like a regular class

Такого нет.

Что касается опубликованного вами дополнения "работает счастливо", это не имеет значения. Когда вы не определяете сущность, которая используется вашей программой, это нарушение правила одного определения. Формально ваша программа некорректна, диагностика не требуется. Это означает, что поведение не определено, и реализации могут свободно связываться с вашей скомпилированной программой по своему усмотрению.

Будьте благодарны лучшим компиляторам группы, дающим вам знать, что вы все испортили, вместо того, чтобы скользить по проблеме.

Другие вопросы по тегам