我正在努力理解P0091r3(已纳入当前C++草案标准N4606的“类模板的模板参数推导”论文)。
我相信我已经理解了它在最简单的情况下是如何工作的,其中template-name仅标识一个模板:
template<class T>
struct S {
S(T);
S(const std::vector<T>&);
};
int main()
{
std::vector<int> v;
auto s = S(v);
}
S
代表主模板,因此我们创建一个虚构的重载集合,其中包括
template<class T> void Sctor(T);
template<class T> void Sctor(const std::vector<T>&);
并对虚构的调用进行重载决议
Sctor(v)
为了确定在这种情况下我们想要调用虚构的Sctor(const std::vector<T>&) [with T=int]
。这意味着我们最终会调用S<int>::S(const std::vector<int>&)
,一切都很好。
我不明白的是,在存在部分特化的情况下,这应该如何工作。
template<class T>
struct S {
S(T);
};
template<class T>
struct S<std::list<T>> {
S(const std::vector<T>&);
};
int main()
{
std::vector<int> v;
auto s = S(v);
}
我們直覺上想要的是對
S<std::list<int>>::S(const std::vector<int>&)
的呼叫。但實際上我們得到了什麼?這個在哪裡被指定了呢?基本上,我不直觀地理解 P0091r3 中 "模板名稱所指定的類別模板" 的含義:這是否意味著主模板,還是包括所有部分特化和明確完全特化呢?
(我也不理解 P0091r3 對 §7.1.6.2p2 的更改如何不破壞使用注入類名(如)的代碼。
template<class T>
struct iterator {
iterator& operator++(int) {
iterator result = *this; // injected-class-name or placeholder?
//...
}
};
但那是一个完全不同的问题。
在任何现有版本的Clang或GCC中是否支持类模板推导和显式推导指南(可能在-f
标志下,例如-fconcepts
)? 如果是这样,我可以在实际情况下尝试一些示例,并可能解决一半的困惑。