variadic模板歧义 - 空参数包

Variadic template ambiguity - empty parameter pack

本文关键字:参数 歧义 variadic      更新时间:2023-10-16

如何删除此代码的歧义?(在这里尝试(

template <typename T>
inline void f()
{   
}
template<typename T, typename ... Args>
inline void f()     
{
    f<Args...>();
}
int main() 
{
    f<char, double, int>();     
    return 0;
}

这是我找到的解决方案...但是我对此并不满意。(在这里尝试(

template <int N>
inline void f()
{ 
}
template<int N, typename T, typename ... Args>
inline void f()     
{
    f<42,Args...>();
}
int main() 
{
    f<42,char, double, int>();     
    return 0;
}

是否可以为空参数包提供模板专业化?

您可以做的是在variadic超载中添加另一个模板参数,例如

template<typename T, typename U, typename ... Args>
inline void f()     
{
    f<U, Args...>();
}

此测量该函数只能使用2个或多个参数调用,因此单个参数或单个参数与空包之间不再有歧义。


根据您要在功能中要实现的目标,如果您可以使用C 17

,也可能可以切换到使用折叠表达式

您根本没有专业的f!您已经超载了。也就是说,您的两个模板名称为 f,这是模棱两可的,您想使用哪个模板。考虑呼叫f<int>()。您的意思是使用T = int或使用T = int; Args = {}实例化第一个模板?如果您想适当地专注于f,我认为它实际上需要包裹成一堂课(以允许部分专业化(:

template<typename T, typename... Args>
struct f_wrapper
{
    static inline void f()
    {
        f_wrapper<Args...>::f();
    }
};

然后,您可以使用此语法对其进行专业化:

template<typename T>
// the brackets v v distinguish specialization from overloading
// you can't overload classes anyway, but it's important for functions
struct f_wrapper<T>
{
    static inline void f()
    {
    }
};

现在,有一个名为f的类模板,该模板具有两个专业。f_wrapper<int>::f()没有歧义。使用T = int; Args = {}实例化的一个和唯一的模板,然后将其用于选择Args = {}专业化(第二个定义(。

您可以继续以下内容:

template<typename T, typename... Args>
inline void f() { f_wrapper<T, Args...>::f(); }