Вопрос:

предупреждение C4661: не предоставлено подходящего определения для явного запроса на создание шаблона

c++ c++11 templates visual-c++ visual-studio-2017

2544 просмотра

1 ответ

308 Репутация автора

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

Чтобы сделать это, я использую «создание шаблона», но экспортирую его, вот так, вот файл заголовка:

#include <iostream>
#include <exception>

using namespace std;

template<typename T>
class __declspec(dllexport) Templated
{
    public:
        Templated();
};

template __declspec(dllexport) Templated<int>;

int main()
{
   cout << "Hello World" << endl; 
}

И определение находится в отдельном файле (.cpp)

template<typename T>
Templated<T>::Templated() {}

template Templated<int>;

Моя проблема в том, что я получил предупреждение, даже если экземпляр помечен как экспортированный!

Вы можете проверить этот код здесь: http://webcompiler.cloudapp.net/ , он выдаст предупреждение C4661!

Это нормально?

Автор: CDZ Источник Размещён: 24.05.2017 01:53

Ответы (1)


6 плюса

85905 Репутация автора

Решение

Вы объявляете явную реализацию вашего шаблона. Это нормально, но вы не можете предоставить определение для конструктора: вы только объявляете его, и нет ни определения для шаблона, ни для его создания.

Вы должны предоставить определение либо в самом шаблоне:

...
public:
    Templated() {};  // empty but defined ctor
...

или для специализации:

Templated<int>::Templated() {
}

От вашего комментария и редактирования до вопроса, определение находится в другом файле cpp. Проблема в том, что для компилятора каждый файл cpp - это отдельная единица перевода . Иначе говоря, когда первый файл компилируется, компилятор не знает другой. Вот почему вы получаете предупреждение, а не ошибку: предупреждение означает, эй, программист, вы заявляете мне, что хотите специализированную реализацию Templated, но я не могу найти его конструктор. Надеюсь, вы определили его в другом модуле перевода, потому что если вы этого не сделаете, вы получите ошибку во время ссылки . Поскольку вы фактически определили его в другом файле, вы можете спокойно проигнорировать предупреждение.

Предупреждение только говорит о том, что происходит что-то необычное . Обычно ожидается, что объявление явной специализации находится в той же единице перевода, что и все ее требуемые определения. И ИМХО, вы должны придерживаться этого использования, чтобы избежать предупреждения и, что более важно, иметь более поддерживаемое приложение.

Автор: Serge Ballesta Размещён: 24.05.2017 02:11
Вопросы из категории :
32x32