2016-04-29 146 views
0

我有一個Painter模板類與paint()模板功能。我正在使用標記專門化模板類中的模板函數。 我已經將Painter.h中的模板函數paint()的定義和Painter.cpp中的函數重載。曖昧模板專業化

當我在Painter.cpp中明確實例化paint()時,出現編譯器錯誤。 我的要求是我需要在Painter.cpp文件中實現重載函數paint(ColorTag<Color::RED>)

源文件如下:

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>); 

我已經試過

首先我創建了一個模板函數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.cppPainter.h。這工作,但打破了我的要求paint(ColorTag<Color::RED>)Painter.cpp超載功能。

有沒有更好的方法來解決這個問題,究竟是什麼導致了模糊性?

回答

-1
#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的

+1

請你回答,你都非常相信,這將100%的工作,「不知道」使得冒險 – piyushj

+0

因爲我沒有檢查它GCC,我讀的地方雙模板是編譯器相關的。 – Jai

0

你想要的是與T = int所以正確的語法明確的分工是:

template<> 
void Painter<int>::paint(ColorTag<Color::RED>); 

有了這個語法,無論是g ++以及鐺編譯代碼。 Live example

0

爲什麼你不能初始化整個類而不是函數?

template class Painter<int>; 
+0

這工作,直到它休息。有時我們不能明確地實例化整個模板類。可以說,我們有兩個結構可以替代'int'。 'struct box {static void foo(){std :: cout <<「foo」;}};''struct Cube {static void bar(){std :: cout <<「Cube」;}};'。使模板函數'paint(ColorTag )'調用'T :: bar()'和專用函數來調用'T :: foo()'。現在嘗試使用「Box」或「Cube」實例化完整的類。 – Vivek

+0

首先注意,在你的代碼'paint(ColorTag )'中不是模板特化,它是'overloaded'函數。其次,我不知道我是否清楚地理解你想要什麼,但是這是你的意思:http://ideone.com/euoiPN – PcAF

+0

是的模板函數不能在模板類中專用。但是使用標籤做了什麼,這讓我看到了僞模板專門化的效果。 **我的要求是我需要Painter.cpp文件本身的專用(標記)功能。**。你可以看到**我試圖修復**,如果你閱讀我的問題結束。正如我在**中說過的,我試圖修復**,如果我在'Painter.cpp'中沒有任何_explicit實例化的情況下將僞專用函數移動到'Painter.h',就可以輕鬆解決問題。 – Vivek