C++ 为什么函数模板不能部分特化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5101516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:23:57  来源:igfitidea点击:

Why function template cannot be partially specialized?

c++language-designtemplate-specializationpartial-specializationfunction-templates

提问by Nawaz

I know the language specification forbids partialspecialization of function template.

我知道语言规范禁止函数模板的部分专业化。

I would like to know the rationale why it forbids it? Are they not useful?

我想知道为什么它禁止它的理由?它们没有用吗?

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!

采纳答案by Cheers and hth. - Alf

AFAIK that's changed in C++0x.

AFAIK 在 C++0x 中发生了变化。

I guess it was just an oversight (considering that you can always get the partial specialization effect with more verbose code, by placing the function as a staticmember of a class).

我想这只是一个疏忽(考虑到您总是可以通过将函数作为static类的成员来使用更冗长的代码来获得部分专业化效果)。

You might look up the relevant DR (Defect Report), if there is one.

您可以查找相关的 DR(缺陷报告),如果有的话。

EDIT: checking this, I find that others have also believed that, but no-one is able to find any such support in the draft standard. This SO threadseems to indicate that partial specialization of function templates is not supported in C++0x.

编辑:检查这一点,我发现其他人也相信这一点,但没有人能够在标准草案中找到任何此类支持。这个 SO 线程似乎表明C++0x 不支持函数模板的部分专业化

EDIT 2: just an example of what I meant by "placing the function as a staticmember of a class":

编辑 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
}

回答by Michal W

Well, you really can't do partial function/method specialization however you can do overloading.

好吧,您确实不能进行部分函数/方法专业化,但是您可以进行重载。

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){...} 

It is the way but I do not know if it satisfy you.

这是方法,但我不知道它是否满足您。

回答by Georgy Pashkov

In general, it's not recommended to specialize function templates at all, because of troubles with overloading. Here's a good article from the C/C++ Users Journal: http://www.gotw.ca/publications/mill17.htm

一般来说,完全不建议专门化函数模板,因为重载会带来麻烦。这是 C/C++ 用户杂志上的一篇好文章:http: //www.gotw.ca/publications/mill17.htm

And it contains an honest answer to your question:

它包含对您问题的诚实回答:

For one thing, you can't partially specialize them -- pretty much just because the language says you can't.

一方面,你不能部分地专门化它们——几乎只是因为语言说你不能。

回答by Kay F. Jahnke

Since you can partially specialize classes, you can use a functor:

由于您可以部分特化类,因此您可以使用函子:

#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 ;
}