59

我知道語言規範禁止部分功能模板的專業化。爲什麼函數模板不能部分專用?

我想知道爲什麼禁止它的原因嗎?他們沒用嗎?

template<typename T, typename U> void f() {} //allowed! 
template<> void f<int, char>()   {} //allowed! 
template<typename T> void f<char, T>() {} //not allowed! 
template<typename T> void f<T, int>()  {} //not allowed! 
+0

對於'模板空隙F(T T,U U){}'也'模板<> void f(int t,char u){}'是允許的。 – dashesy 2016-07-22 21:46:44

+2

我覺得有趣的是,當問題不是「我怎麼能達到類似的目標」,而是「這種行爲背後的原因是什麼」時,人們總是提供解決方法......我自己不知道這個選擇的原因,但我認爲委員會必須有理由禁止功能模板部分專業化。到目前爲止,「最接近」的解釋是Georgy發佈的鏈接,該鏈接僅指出存在過載時功能模板部分專業化的潛在「風險」。但是,我不認爲這是禁止此功能的理由,所以我認爲還有更多這樣的內容。 – bartgol 2017-10-03 19:58:39

回答

45

AFAIK在C++ 0x中被更改。

我想這只是一個疏忽(考慮到你總是可以通過放置函數作爲類的一個static成員來獲得部分專業化效果和更詳細的代碼)。

如果有相關DR(缺陷報告),您可以查看相關DR(缺陷報告)。

編輯:檢查這一點,我發現其他人也相信,但沒有人能夠在標準草案中找到任何此類支持。 This SO thread似乎表示函數模板的部分特化在C++ 0x中不受支持。

編輯2:只是我的意思是「將函數作爲類的static成員」的例子:

#include <iostream> 
using namespace std; 

// template<typename T, typename U> void f() {} //allowed! 
// template<> void f<int, char>()   {} //allowed! 
// template<typename T> void f<char, T>() {} //not allowed! 
// template<typename T> void f<T, int>()  {} //not allowed! 

void say(char const s[]) { std::cout << s << std::endl; } 

namespace detail { 
    template< class T, class U > 
    struct F { 
     static void impl() { say("1. primary template"); } 
    }; 

    template<> 
    struct F<int, char> { 
     static void impl() { say("2. <int, char> explicit specialization"); } 
    }; 

    template< class T > 
    struct F< char, T > { 
     static void impl() { say("3. <char, T> partial specialization"); } 
    }; 

    template< class T > 
    struct F< T, int > { 
     static void impl() { say("4. <T, int> partial specialization"); } 
    }; 
} // namespace detail 

template< class T, class U > 
void f() { detail::F<T, U>::impl(); }  

int main() { 
    f<char const*, double>();  // 1 
    f<int, char>();     // 2 
    f<char, double>();    // 3 
    f<double, int>();    // 4 
} 
+0

您是否擁有n3225的標準?我做了一個快速搜索,但找不到它:/ – 2011-02-24 08:14:22

+0

@Matthieu M .: [n3225.pdf](http://std.dkuug.dk/jtc1/sc2/wg2/docs/n3225.pdf) – 2011-02-24 09:19:31

+1

啊對不起。 ..一個字不見了。我有文檔,但無法找到特定的*段*。雖然給你的編輯,我想這只是因爲它不在那裏:) – 2011-02-24 09:25:45

13

在一般情況下,不建議在所有專門函數模板,因爲超負荷的麻煩。下面是從C/C++用戶日報的一篇好文章:http://www.gotw.ca/publications/mill17.htm

而且它包含一個誠實的回答你的問題:

一件事,你不能部分專門它們 - 非常簡單,只是因爲該語言說你不能。

+0

除了它被提及一次之外,文章不是關於部分專業化。 – 2017-10-17 13:52:59

8

那麼,你真的不能做部分功能/方法專業化,但你可以做超載。

template <typename T, typename U> 
T fun(U pObj){...} 

// acts like partial specialization <T, int> AFAIK 
// (based on Modern C++ Design by Alexandrescu) 
template <typename T> 
T fun(int pObj){...} 

這是方式,但我不知道它是否讓你滿意。

+1

哇,我的腦海裏充滿了模板,我真的忘了它有多簡單:) – Johannes 2017-02-01 14:28:12

6

既然可以部分地專門的類,則可以使用一個算符:

#include <iostream> 

template < typename dtype , int k > struct fun 
{ 
int operator()() 
{ 
    return k ; 
} 
} ; 

template < typename dtype > struct fun < dtype , 0 > 
{ 
int operator()() 
{ 
    return 42 ; 
} 
} ; 

int main (int argc , char * argv[]) 
{ 
std::cout << fun<float,5>()() << std::endl ; 
std::cout << fun<float,0>()() << std::endl ; 
} 
+0

然後你可以使用一個函數模板來調用,擺脫醜陋的'()()'語法。 – tmr232 2016-12-04 15:47:53

相關問題