2015-01-23 4 views
1

Я пытаюсь написать код для преобразования изображения opencv в QImage. Я хочу реализовать это как общую функцию, используя шаблоны. Это то, что у меня есть:C++ template function multiple instantiation

#include <QImage> 
#include <opencv2/core/core.hpp> 

void setPixel(int j, int i, unsigned char v, QImage & img) 
{ 
    img.setPixel(j, i, qRgb(v, v, v)); 
}   

void setPixel(int j, int i, cv::Vec3b v, QImage & img) 
{ 
    img.setPixel(j, i, qRgb(v[2], v[1], v[0])); 
} 

template <typename ImageType> 
QImage toQImageARGB (const cv::Mat & image) 
{ 
    QImage res(image.cols, image.rows, QImage::Format_ARGB32_Premultiplied); 
    ImageType tmp; 
    for (int i = 0; i < image.rows; ++i) 
    { 
     for (int j = 0; j < image.cols; ++j) 
     { 
      tmp = image.at<ImageType>(i,j); 
      setPixel(j, i, tmp, res); 
     } 
    } 
    return res; 
} 

я получаю ошибку компиляции времени

CMakeFiles/annotate.dir/main.cpp.o: In function `std::remove_reference<cv::ximgproc::SuperpixelSEEDS*&>::type&& std::move<cv::ximgproc::SuperpixelSEEDS*&>(cv::ximgproc::SuperpixelSEEDS*&)': 
.../util.h:8: multiple definition of `setPixel(int, int, unsigned char, QImage&)' 
CMakeFiles/annotate.dir/moc_widget.cxx.o:.../build/../util.h:8: first defined here 
CMakeFiles/annotate.dir/main.cpp.o: In function `cv::Vec<unsigned char, 3> const& cv::Mat::at<cv::Vec<unsigned char, 3> >(int, int) const': 
.../util.h:13: multiple definition of `setPixel(int, int, cv::Vec<unsigned char, 3>, QImage&)' 
CMakeFiles/annotate.dir/moc_widget.cxx.o:.../build/../util.h:13: first defined here 
collect2: error: ld returned 1 exit status 
make[2]: *** [...] Error 1 
make[1]: *** [CMakeFiles/annotate.dir/all] Error 2 
make: *** [all] Error 2 

от моего основного метода.

Можно ли это сделать с помощью шаблонов функций, и это имеет смысл?

ответ

2

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

Если вы хотите определения этих функций появляются в файле заголовка, объявить их как inline:

inline void setPixel(int j, int i, unsigned char v, QImage & img) 
{ 
    img.setPixel(j, i, qRgb(v, v, v)); 
}   

inline void setPixel(int j, int i, cv::Vec3b v, QImage & img) 
{ 
    img.setPixel(j, i, qRgb(v[2], v[1], v[0])); 
} 
+0

Я оборачивать 'util.h' заголовочный файл в моем' CMakeLists.txt'. У этого также есть '# ifndef' охранники. Я добавил полную ошибку компиляции. – fuji

+1

@ j.dog: Прежде всего, эти ошибки происходят не от компилятора, а от компоновщика. Во-вторых, защитники заголовков не защищают вас от множества включений определений функций из разных .cpp-файлов. Для получения дополнительной информации см. Второй вопрос/ответ в [этот пост] (http://stackoverflow.com/questions/14909997/why-arent-my-include-guards-preventing-recursive-inclusion-and-multiple-symbol) , Чтобы устранить проблему, просто объявите эти функции как «inline» или переместите их определение в файл .cpp (оставляя объявления только в заголовке). –