调用variadic函数模板时C++ 11模糊重载

Tru*_*uLa 5 c++ variadic-templates

你能否解释一下我为什么要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;
};
Run Code Online (Sandbox Code Playgroud)

编辑

模棱两可的原因是两个因素的结合.第一个是在调用中应用的简单重载规则func(args...).第二个是简单函数不能通过value和const引用重载.为了确保,一个可以调用替换wrap<const Test &>(t)func(static_cast<const Test &>(t)).错误仍然存​​在.

要解决这个问题,可以使用函数模板func和值与const参考模板特化,如@lubgr提供的示例所示

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

lub*_*bgr 2

通过wrap显式实例化函数模板,想象编译器处于wrap实例化状态,知道Targs...确实是const Test&. 那么应该选择哪个函数重载呢?它不能选择其中一个,因为 的模板参数wrap不会传播到普通(非模板)函数。相反,应用简单的过载规则。

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;
}
Run Code Online (Sandbox Code Playgroud)

当您明确要求时,就会调用适当的专业化。

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