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

相关问题