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

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

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

  1. #include <iostream>
  2. template <typename T>
  3. struct Arity {};
  4. template <typename Ret, typename... Args>
  5. struct Arity<Ret(Args...)>
  6. : std::integral_constant<size_t, sizeof...(Args)>
  7. {};
  8. int func1(int a, int b) { return a + b; }
  9. template <typename F>
  10. void someFuncTemplate(F)
  11. {
  12. std::cout << Arity<F>::value;
  13. }
  14. int main()
  15. {
  16. std::cout << Arity<decltype(func1)>::value << '\n';
  17. //someFuncTemplate(func1);
  18. }
mwngjboj

mwngjboj1#

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

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

您还可以添加

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

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

  1. template <typename F>
  2. void someFuncTemplate(F&&) {
  3. std::cout << Arity<F>::value;
  4. }

Demo

展开查看全部
quhf5bfb

quhf5bfb2#

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

  1. // preceding unchanged
  2. template <typename F>
  3. void someFuncTemplate(F const &)
  4. //......................^^^^^^^
  5. {
  6. std::cout << Arity<F>::value;
  7. }
  8. int main()
  9. {
  10. someFuncTemplate(func1);
  11. }

相关问题