繁体   English   中英

调用可变参数函数模板时C ++ 11模棱两可的重载

[英]C++11 ambiguous overload when calling variadic function template

您能否解释为什么会error: call of overloaded 'func(const Test&)' is ambiguous尽管我使用显式模板实例化,但是error: call of overloaded 'func(const Test&)' is ambiguous的?

#include <iostream>

struct Test {
};

void func(const Test &) {
  std::cout << "By Reference" << std::endl;
}

void func(const Test) {
  std::cout << "By Value" << std::endl;
}

template <typename... TArgs>
void wrap(TArgs... args) {
  func(args...);
}

int main() {
  Test t;
  wrap<const Test &>(t);
  return 0;
};

编辑

歧义的原因是两个因素的结合。 首先是在func(args...)调用中应用了简单的重载规则。 第二个是简单函数不能被值和const引用重载。 为了确保这一点,可以将调用wrap<const Test &>(t)替换为func(static_cast<const Test &>(t)) 错误仍然存​​在。

要解决此问题,可以使用函数模板进行func和值与const引用模板的专门化,如@lubgr提供的示例所示

谢谢大家帮助我揭开这个概念的神秘面纱。

出于相同的原因,以下调用是不明确的:

#include <iostream>
void foo(int) { std::cout << "val" << std::endl; }
void foo(const int&) { std::cout << "ref" << std::endl; }

int main()
{
  int i = 1;
  foo(i);
}

请参阅此处以获取对该案例的完整讨论。

在显式实例化wrap函数模板的情况下,想象一下编译器在wrap实例中,因为知道Targs...实际上是const Test& 那么应该选择哪个函数重载? 它不能选择一个,因为wrap的template参数不会传播到普通(非模板)函数。 而是应用简单的重载规则。

如果您也将func更改为函数模板,则可以看到差异并解决问题:

template <class T> void func(T);

template <> void func<const Test&>(const Test&) {
  std::cout << "By Reference" << std::endl;
}

template <> void func<const Test>(const Test) {
  std::cout << "By Value" << std::endl;
}

然后,在您明确要求时调用适当的专业化。

template <typename... TArgs>
void wrap(TArgs... args) {
  func<TArgs...>(args...); // Note, the type is specified here, again.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM