У меня есть Painter
шаблон класс с paint()
шаблон функции. Я использую теги, чтобы специализировать функцию шаблона внутри класса шаблона. Я разместил определение функции шаблона paint()
внутри Painter.h
и перегруженной функции внутри Painter.cpp
.Неоднозначный шаблон специализации
Я получаю ошибку компилятора, когда я явно создаю экземпляр paint()
в Painter.cpp
. Мое требование в том, что мне нужна реализация перегруженной функции paint(ColorTag<Color::RED>)
в файле Painter.cpp.
Исходные файлы следующим образом:
Painter.h
#include <iostream>
enum class Color {
RED = 0,
GREEN = 1,
BLUE = 2
};
template<Color>
struct ColorTag {
};
template<typename T>
class Painter {
public:
template<Color MyColor>
void paint(ColorTag<MyColor>);
void paint(ColorTag<Color::RED>);
};
template<typename T>
template<Color MyColor>
void Painter<T>::paint(ColorTag<MyColor>){
std::cout << "General" << std::endl;
}
Painter.cpp
#include "Painter.h"
template<typename T>
void Painter<T>::paint(ColorTag<Color::RED>){
std::cout << "RED" << std::endl;
}
template void Painter<int>::paint(ColorTag<Color::RED>);
main.cpp
#include "Painter.h"
int main(){
Painter<int> painter;
painter.paint(ColorTag<Color::RED>());
return 0;
}
Составлено с использованием
g++ Main.cpp Painter.cpp -std=c++11
Я получаю следующее сообщение об ошибке компилятора, когда я явно экземпляр paint()
в Painter.cpp
Painter.cpp:8:15: error: ambiguous template specialization ‘paint<>’ for ‘void Painter<int>::paint(ColorTag<(Color)0>)’
template void Painter<int>::paint(ColorTag<Color::RED>);
^
Painter.cpp:4:6: note: candidates are: void Painter<T>::paint(ColorTag<(Color)0>) [with T = int]
void Painter<T>::paint(ColorTag<Color::RED>){
^
In file included from Painter.cpp:1:0:
Painter.h:20:10: note: template<Color MyColor> void Painter<T>::paint(ColorTag<MyColor>) [with Color MyColor = MyColor; T = int]
void paint(ColorTag<MyColor>);
То, что я пытался
Во-первых I создал шаблон functio n называется instantiatePaint()
для вызова paint()
функция. Затем я разместил и создал его в файле Painter.cpp
. Это сработало. Но такого рода чувствует себя неловко.
template<typename T>
template<Color MyColor>
void Painter<T>::instantiatePaint(ColorTag<MyColor>){
paint(ColorTag<MyColor>());
}
template void Painter<int>::instantiatePaint(ColorTag<Color::RED>);
Во-вторых переехал перегружен определение функции от Painter.cpp
к Painter.h
. Это работает, но нарушает мое требование о перегрузке функции paint(ColorTag<Color::RED>)
в Painter.cpp
.
Есть ли какие-либо более эффективные способы решения проблемы или что именно вызывает неоднозначность?
пожалуйста, ответьте, вы очень уверены, что это будет 100% работать, «не уверен» делает рискованный – piyushj
, потому что я не проверил это на GCC, я где-то читал двойной шаблон компилятор зависит. – Jai