我想知道如何解决对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
),正确?
答案 0 :(得分: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&&
(需要用户定义的字符串文字转换),第二个采用const char(&)[12]
(这是完全匹配)。因此,第二个重载具有更好的转换顺序,是首选。