简体   繁体   English

具有非类型参数的模板的部分特化规则

[英]Rules for partial specialization of templates with nontype parameter(s)

Consider the following template考虑以下模板

template <typename T, int v> void func(const T&x);

and I want to specialize it for some class A .我想将它专门用于某个类A Here is my try (by referring to this ):这是我的尝试(通过参考这个):

template <int v> void func<A, v>(const A&x);

However, that's illegal.然而,这是违法的。 My question is why this is illegal (which rule it breaks) and if that is against the grammar, is there other ways for us to specialize it for A ?我的问题是为什么这是非法的(它违反了哪个规则),如果这违反语法,我们还有其他方法可以将它专门用于A吗?

You cannot partially specialize a function template but you can overload it as shown below.你不能部分特化一个函数模板,但你可以重载它,如下所示。

#include <iostream>
class A 
{
    
};

template <typename T, int v> void func(const T&x) //primary template
{
    std::cout<<"primary template"<<std::endl;
}
//this is an overload and not a specialization. Also partial specialization cannot be done for function templates
template <int v> void func(const A&x)
{
    std::cout<<"overload not specialization"<<std::endl;
}
int main()
{
    func<int, 5>(84); //uses primary template 
    
    func<5>(A()); //uses the overloaded version
    return 0;
}

Function templates cannot be partially specialized, hence the error:函数模板不能部分特化,因此出现错误:

<source>:8:23: error: non-class, non-variable partial specialization 'func<A, v>' is not allowed
    8 | template <int v> void func<A, v>(const A&x);
      |                       ^~~~~~~~~~

You can for example partially specialize a type with operator() :例如,您可以使用operator()部分特化一个类型:

template <typename T, int v>
struct func{
    void operator()(const T&x);
};

struct A {};

template <int v> 
struct  func<A, v>{
    void operator()(const A&x);
};

you can do it with你可以用

template <typename T, int v> void func(const T&x);
template <int v> void func(const A&x);

as for why, I think it mainly because it provide no additional value至于为什么,我认为主要是因为它没有提供额外的价值

template <typename T> void func(const T&x);
template <typename T> void func(const T*x);
void func(const A&);

is already a valid function "specialization" .已经是一个有效的函数"specialization" not really specialization in the sense of standard wording在标准措辞的意义上并不是真正的专业化

You can use constraint (or SFINAE) to do it.您可以使用约束(或 SFINAE)来做到这一点。

#include <iostream>
class A {};
class B {};

template <typename T, int v> void func(const T&)
{
    std::cout<<"generic";
}

template <typename T, int v> void func(const T&)
requires std::is_same_v<T,A>
{
    std::cout<<"A";
}

int main(){
    func<A,1>(A{}); // output A
}

https://godbolt.org/z/YcxeoofYE https://godbolt.org/z/YcxeoofYE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM