2016-07-11 29 views
3

我不知道如何调用的std::make_optional这两个重载得到解决:函数模板重载分辨率混乱

template< class T > 
constexpr std::optional<std::decay_t<T>> make_optional(T&& value); 

template< class T, class... Args > 
constexpr std::optional<T> make_optional(Args&&... args); 

我知道没有明确的模板参数像make_optional(123)将调用第一个调用,但如何make_optional<int>(123)?哪些超载将被选择,以及按照什么规则?

UPDATE:如果我写说make_optional<string>("hello world"),我会调用第二个重载(即使字符串文字可以被隐式转换为string),是否正确?

+1

库(和名称空间)在哪里声明它们? ['std :: experimental'](http://en.cppreference.com/w/cpp/header/experimental/optional)似乎只定义了第一个。 – Nawaz

+0

@Nawaz:'make_optional'的第二个重载来自[P0032(PDF)](http://wg21.link/P0032),它[在Oulu之前转发给LWG](https://issues.isocpp.org /show_bug.cgi?id=100),显然。虽然P0091可能会使它过时,所以他们可能没有采用它。所以目前纳瓦兹是正确的:第二次超载不存在。 –

+0

@NicolBolas [它存在](https://github.com/cplusplus/draft/commit/1882aa320a101fcfdb7a6d4de40197982209ce30)。 –

回答

2

重载分辨率从确定可行候选项开始,选择具有最佳转换顺序的项目,然后查看tiebreakers列表。


make_optional(123)仅具有一个可行的候选,因为T处于第二过载的非推导出上下文。因此,它是最好的可行候选人。


make_optional<int>(123)给了我们两个可行的候选人:

  • make_optional(int&&)[T=int]
  • make_optional<int>(int&&)[T=int, Args={int}]

功能采取同样的参数(int&&),所以他们同样平凡可用相同的转换序列进行。第一个重载是比第二个重载更专用的函数模板(因为它只接受一个参数而不是可变参数包),所以它是首选。


make_optional<string>("hello world")给了我们两个可行的候选人:

  • make_optional(string&&)[T=string]
  • make_optional<string>(const char(&)[12])[T=string, Args={const char (&)[12]}]

这里,两个函数不采取同样的观点 - 第一需要一个string&&(这将需要用户定义的字符串转换)和th e秒需要一个const char(&)[12](这是一个完全匹配)。因此,第二次过载具有更好的转换顺序并且是优选的。