c++ 如何解决这种可变模板歧义

uubf1zoe  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(156)

只要注解掉someFuncTemplate(func1),下面的代码就可以编译并正常运行。然而,一旦它被取消注解,编译就会失败,并出现错误“'value' is not a member of 'Arity<int(*)(int,int)>'”编译错误,我认为这是由于编译器选择了第一个模板而不是第二个模板。我试着从第一个模板中删除括号,但问题仍然存在,只是这次出现了一个“不完整的类型”编译错误。
如何在使用Arity<F>时强制编译器选择正确的模板?

#include <iostream>

template <typename T>
struct Arity {};

template <typename Ret, typename... Args>
struct Arity<Ret(Args...)>
    : std::integral_constant<size_t, sizeof...(Args)> 
{};

int func1(int a, int b) { return a + b; }

template <typename F>
void someFuncTemplate(F)
{
    std::cout << Arity<F>::value;
}

int main()
{
    std::cout << Arity<decltype(func1)>::value << '\n';
    //someFuncTemplate(func1);
}
mwngjboj

mwngjboj1#

您需要为第二种情况添加另一个专门化:

template <typename Ret, typename... Args>
struct Arity<Ret (*)(Args...)> : Arity<Ret(Args...)> {};
//               ^^^

您还可以添加

template <typename Ret, typename... Args>
struct Arity<Ret (&)(Args...)> : Arity<Ret(Args...)> {};

为了使一个函数声明,如下面的工作:

template <typename F>
void someFuncTemplate(F&&) {
    std::cout << Arity<F>::value;
}

Demo

quhf5bfb

quhf5bfb2#

作为为函数指针添加专门化的替代方案,您可以修改someFunctTemplate以通过引用获取其参数:

// preceding unchanged

template <typename F>
void someFuncTemplate(F const &)
//......................^^^^^^^
{
    std::cout << Arity<F>::value;
}

int main()
{
    someFuncTemplate(func1);
}

相关问题