C++ 专门化具有多个值和相同专门化的非类型模板函数

C++ 专门化具有多个值和相同专门化的非类型模板函数,c++,templates,template-specialization,C++,Templates,Template Specialization,我的意思是有一个依赖于size\ttemplate参数的模板化函数。 我有一个“后备”定义,放在我的sfinae.h中 template <size_t dim> int sumVec(void) { return -1; } 它的原型在sfinae.h中 template <size_t dim> int sumVec(void) { return -1; } 现在我想定义一个专门化,它适用于dim的多个值,因此我的意思是避免重复多次。 我可以将di

我的意思是有一个依赖于
size\t
template参数的模板化函数。 我有一个“后备”定义,放在我的
sfinae.h

template <size_t dim>
int sumVec(void) {
    return -1;
}
它的原型在
sfinae.h

template <size_t dim>
int sumVec(void) {
    return -1;
}
现在我想定义一个专门化,它适用于
dim
的多个值,因此我的意思是避免重复多次。 我可以将
dim
设置为
enum类
,如中所述

我的问题是 我能否在不(大量)更改现有代码(但我可以添加到代码中)的情况下实现我的目标?

我尝试在标题或源代码中添加下面的代码,编译器(gcc 10.2.0)抛出了一个错误
不允许使用非类、非变量的部分专门化“sumVec”
因此,我不确定我是否使用了正确的方法或语法,或者我提出的问题是编译器不允许的

template<size_t dim>
int sumVec<std::enable_if<dim == 3 || dim == 4>>(void)
{
    return dim;
};
模板
int sumVec(无效)
{
返回暗淡;
};

函数模板不能部分专用化。您可以通过重载应用SFINAE,这需要更改主模板以避免不明确的调用

// primary template overloading #1
template<size_t dim>
std::enable_if_t<dim != 3 && dim != 4, int> sumVec(void)
{
    return -1;
}

// primary template overloading #2
template<size_t dim>
std::enable_if_t<dim == 3 || dim == 4, int> sumVec(void)
{
    return dim;
}

// full specialization
template <>
int sumVec<2>(void) {
    return 2;
}
//主模板重载#1
模板
std::如果sumVec(无效)启用
{
返回-1;
}
//主模板重载#2
模板
std::如果sumVec(无效)启用
{
返回暗淡;
}
//完全专业化
模板
int sumVec(无效){
返回2;
}

函数模板不能部分专用化。您可以通过重载应用SFINAE,这需要更改主模板以避免不明确的调用

// primary template overloading #1
template<size_t dim>
std::enable_if_t<dim != 3 && dim != 4, int> sumVec(void)
{
    return -1;
}

// primary template overloading #2
template<size_t dim>
std::enable_if_t<dim == 3 || dim == 4, int> sumVec(void)
{
    return dim;
}

// full specialization
template <>
int sumVec<2>(void) {
    return 2;
}
//主模板重载#1
模板
std::如果sumVec(无效)启用
{
返回-1;
}
//主模板重载#2
模板
std::如果sumVec(无效)启用
{
返回暗淡;
}
//完全专业化
模板
int sumVec(无效){
返回2;
}

如果constexpr,您可以使用
避免模板专业化,而只需要类的一个实例:

template <size_t dim>
int sumVec(void) {
    if constexpr (dim == 2) {
       return 2;
    }
    if constexpr (dim == 3 || dim == 4) {
       return dim;
    }
    return -1;
}
模板
int sumVec(无效){
如果constexpr(dim==2){
返回2;
}
if constexpr(dim==3 | | dim==4){
返回暗淡;
}
返回-1;
}

如果constexpr
,您可以使用
避免模板专业化,而只需要类的一个实例:

template <size_t dim>
int sumVec(void) {
    if constexpr (dim == 2) {
       return 2;
    }
    if constexpr (dim == 3 || dim == 4) {
       return dim;
    }
    return -1;
}
模板
int sumVec(无效){
如果constexpr(dim==2){
返回2;
}
if constexpr(dim==3 | | dim==4){
返回暗淡;
}
返回-1;
}


如果constexpr
在其实现中取决于您实际要实现的目标,那么您可能只需要一个类就可以使用
。如果不更改sfinae.h.@AlanBirtles,则无法实现这一目标-到目前为止,我还没有任何类。我欢迎你发布一个简单的例子,说明你的想法。至于我想要的是什么,这将是很长的时间来解释,我不确定这会改变问题。。。我想这不应该被视为一个,我目前在张贴的MCVE感兴趣。。。如果不够清楚,请告诉我。@bipll-请参阅更新的操作。。。我的意思是不进行实质性的更改。如果constexpr
在其实现中取决于您实际要实现的目标,那么您可能只需要一个类并使用
,而不更改sfinae.h.@AlanBirtles-到目前为止,我没有任何类。我欢迎你发布一个简单的例子,说明你的想法。至于我想要的是什么,这将是很长的时间来解释,我不确定这会改变问题。。。我想这不应该被视为一个,我目前在张贴的MCVE感兴趣。。。如果不够清楚,请告诉我。@bipll-请参阅更新的操作。。。我的意思是不会对它进行实质性的更改。如果将所有内容都放在页眉中,这是有效的。在源代码中放置定义的正确方法是什么,在标题中只保留原型?我试图声明
inline
几种组合,但我没有理由决定正确的组合。@sancho.srestemonicacellio这不容易实现。我早就意识到了这一点,事实上,我过去也曾对其进行过投票。但是我在其他地方的源代码中使用了显式实例化,例如,在这里,我的
sumVec
是在源代码中定义的。但是我无法在源代码中定义两个
std::enable\u if\u t…
。我想,如果选择合适的
内联
s(我没有得到),它应该会起作用。@sancho.srestemonicacellio主模板必须在使用它们的每个翻译单元中都可见,我认为它们必须放在Header中,并在必要时包括在内。顺便说一句:如果你把专门化放在cc文件中,它不包括在内,即在翻译单元中不可见,那么就会调用主模板。“函数模板不能部分专门化。”这不完全正确。在主定义中使用
if constexpr
可以获得某种程度的部分专门化。如果将所有内容都放在标题中,则可以实现此功能。在源代码中放置定义的正确方法是什么,在标题中只保留原型?我试图声明
inline
几种组合,但我没有理由决定正确的组合。@sancho.srestemonicacellio这不容易实现。我早就意识到了这一点,事实上,我过去也曾对其进行过投票。但是我在其他地方的源代码中使用了显式实例化,例如,在这里,我的
sumVec
是在源代码中定义的。但是我无法在源代码中定义两个
std::enable\u if\u t…
。我想,如果选择合适的
内联
s(我没有得到),它应该会起作用。@sancho.srestemonicacellio主模板必须在使用它们的每个翻译单元中都可见,我认为它们必须放在Header中,并在必要时包括在内。顺便说一句:如果你把专门化放在cc文件中,它没有包括在内,即在翻译单元中不可见,那么就会调用主模板