有没有办法为指针和数组提供单独的模板函数重载?

问题描述 投票:0回答:1

首先,我想特别强调 C++20 标签,因为我相信使用概念和

requires
语句更容易解决这个问题。

其次,当我在这里说数组时,我的意思是

int a[3]
,我已经有一个工作重载来处理“正常”std容器,包括
array<int, 3> b
(另一个用于
map
类容器,另一个用于
queue
) -类似容器)。

我有一个带有大量重载的大型函数,可以使用新概念和

requires
关键字来处理不同类型,以使每个重载处理尽可能多的类型。

我找不到正确区分数组和指针的方法。我想要一种永远不会将指针错误分类为数组的方法,但是如果某些数组被分类为指针,那并不是世界末日(值得注意的是,如果一个数组只有一个元素,那么它被分类为哪个元素根本不重要)如)。

这个答案很接近,但它不适用于我不知道数组是什么/指针是什么的一般情况。

现在我将其用于数组:

template<typename T> requires(requires(T& a){1[a];}
                                 && !requires(T& a){a.begin();}
                                 && !is_convertible_v<T, string>
                                 )
         string function(const T& v);

这是指针:

template<typename T> requires(is_pointer_v<T>
                                && !requires(T& a){1[a];}
                                && !is_convertible_v<T, string>
                                )
        string function(T v);

这至少可以将指向字符串的类用作指针,但我尝试的其他所有内容都被归类为数组。

我认为

<type_traits>
is_array_v<T>
可以在这里工作;如果我将它添加到我对数组的要求中,并在我对指针的要求中将
!requires(T& a){1[a];}
替换为
!is_array_v<T>
,那么指针将按预期工作,但我会得到一个不明确的数组重载错误,因为它隐式地将其转换为指针。我的印象是隐式转换在模板实例化中不起作用。

c++ templates overloading c++20 c++-concepts
1个回答
0
投票

您可以根据传递的函数参数进行函数模板重载,而不是使用

requires
使用约束。

由于在代码片段的数组版本中您是通过引用传递的,因此您只需将参数更改为

const T (&ref)[N]
即可,如下所示。同样,由于在指针版本中您是按值传递的,因此您只需将其参数更改为
T*
,如下所示:

//for arrays only
template<typename T, std::size_t N> void func(const T(&ref)[N])
{
}

//for pointers only
template<typename T> void func(T*)
{
}
© www.soinside.com 2019 - 2024. All rights reserved.