[英]Ambiguous template specialization
我有一个带有paint()
模板函数的Painter
模板类。 我正在使用标记来专门化模板类中的模板功能。 我已经把模板函数定义paint()
内Painter.h
和重载的内部功能Painter.cpp
。
当我在Painter.cpp
显式实例化paint()
, Painter.cpp
编译器错误。 我的要求是我需要在文件Painter.cpp中实现重载功能paint(ColorTag<Color::RED>)
的实现。
源文件如下:
画家
#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
当我在Painter.cpp中显式实例化paint()
,出现以下编译器错误
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>);
我尝试过的
首先,我创建了一个名为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
。 这可以工作,但违反了我在Painter.cpp
中具有重载功能paint(ColorTag<Color::RED>)
的Painter.cpp
。
有没有更好的方法来解决问题,或者到底是什么引起歧义?
您想要的是T = int
的显式专业化,因此正确的语法是:
template<>
void Painter<int>::paint(ColorTag<Color::RED>);
使用这种语法,g ++和clang都可以编译代码。 现场例子
为什么不能初始化整个类而不是函数?
template class Painter<int>;
#include <iostream>
enum Color {
RED = 0,
GREEN = 1,
BLUE = 2
};
template<Color color = Color::RED>
struct ColorTag
{
// your Implementation
};
template<>
struct ColorTag <Color::RED>
{
// your Implementation specific to Color::RED
};
template<typename T>
class Painter {
public:
// template specialization can not apply on method level
// use class or struct
template<Color MyColor>
void paint(ColorTag<MyColor>);
};
template<typename T>
template<Color MyColor>
void Painter<T>::paint(ColorTag<MyColor> colorTag)
{
std::cout << "General"<<std::endl;
}
在Visual Studio 2012上无法正常使用Gcc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.