【问题标题】:Call to variadic template is ambigous对可变参数模板的调用不明确
【发布时间】:2015-10-27 11:01:56
【问题描述】:

我有一个可变参数模板函数,除非我使用与T 相同类型的参数调用它。

template <typename T, typename... Arg>
std::shared_ptr<T> make_shared(Arg&&... arg)
{
    return std::shared_ptr<T>(new T(std::forward<Arg>(arg)...));
}

工作电话:

auto sahredStr = make_shared<std::string>("fubar"); 

模棱两可的称呼:

std::string str = "fubar";
auto sharedStr = make_shared<std::string>(str);  

我想了解第二次通话有什么问题。

LIVE DEMO

【问题讨论】:

  • 后者通过ADL找到std::make_shared
  • @PiotrSkotnicki 谢谢你:)
  • 要么改名字,要么用(make_shared&lt;std::string&gt;)(str)语法调用它
  • @PiotrSkotnicki 你可以回答这个问题,我会接受的。毕竟,你可能在我弄明白之前为我节省了相当长的时间:)

标签: c++ templates ambiguous


【解决方案1】:

对于使用非限定名称调用函数,名称查找过程还考虑在其中声明参数类型(及其类型模板参数)的命名空间 - 也称为 Argument Dependent Lookup .对于std::string 类型的参数,这意味着make_shared 函数也在std 命名空间中被搜索。因此,可行的重载集还包括 std::make_shared 函数,因此存在歧义。

解决方案是更改函数名称以避免与std 的重载冲突,或者将函数名称用括号括起来:

auto sharedStr = (make_shared<std::string>)(str);
//              ~^~                      ~^~

【讨论】:

  • 为什么括号在这里起作用?我会使用::make_shared&lt;std::string&gt;(str) 来明确选择正确的命名空间。
  • @CK1 括号禁用 ADL
猜你喜欢
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2018-03-20
  • 2017-10-12
相关资源
最近更新 更多