【发布时间】:2016-09-07 07:39:50
【问题描述】:
我正在尝试理解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 的“由 template-name 指定的类模板”是什么意思:这是指主模板,还是包括所有部分特化和显式完整还有专业吗?
(我也不明白 P0091r3 对 §7.1.6.2p2 的更改如何不使用 injected-class-name 破坏代码,例如
template<class T>
struct iterator {
iterator& operator++(int) {
iterator result = *this; // injected-class-name or placeholder?
//...
}
};
但这完全是一个不同的问题。)
任何现存版本的 Clang 或 GCC 是否支持类模板推导和显式推导指南(可能在 -f 标志下,如 -fconcepts 是)?如果是这样,我可以在现实生活中尝试其中一些示例,并且可能会消除我一半的困惑。
【问题讨论】:
-
到目前为止,没有主要编译器(可能根本没有编译器)支持构造函数的模板参数推导。如果我没记错的话,可能在某个地方有一个 Clang 分支,用于收集实施经验,但我什至不确定它是否可以在线获得。
标签: c++ templates language-lawyer template-meta-programming c++17