gpt4 book ai didi

c++ - 关于C++17中类模板参数推导的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:00:23 26 4
gpt4 key购买 nike

我正在尝试理解 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 的更改如何不破坏使用注入(inject)类名的代码,例如

template<class T>
struct iterator {
iterator& operator++(int) {
iterator result = *this; // injected-class-name or placeholder?
//...
}
};

但这完全是另一个问题。)


类模板推导和显式推导指南是否在任何现有版本的 Clang 或 GCC 中受支持(可能在 -f 标志下,如 -fconcepts 是)?如果是这样,我可以在现实生活中尝试其中的一些示例,并且可能会消除一半的困惑。

最佳答案

提案略过了这一点,但我认为其意图是仅考虑主类模板的构造函数。证据是新的 [class.template.deduction] 有:

  • For each constructor of the class template designated by the template-name, a function template with the following properties is a candidate: [...]

如果我们谈论的是“the”类模板,那么这是主要的类模板,特别是因为类模板部分特化无法通过名称查找找到 ([temp.class.spec]/6)。这也是原型(prototype)实现(见下文)的行为方式。

在本文中,类模板部分特化在“隐式推导指南的优缺点”一节中进行了考虑,而是担心主类模板中的构造函数可能会触发硬(非 SFINAE)错误:

template<class T> struct X {
using ty = T::type;
static auto foo() { return typename T::type{} };
X(ty); #1
X(decltype(foo())); #2
X(T);
};
template<class T>
struct X<T*> {
X(...);
};
X x{(int *)0};

您请求考虑类模板偏特化构造函数的请求从表面上看是合理的,但请注意,这可能会导致歧义:

template<class T> struct Y { Y(T*); };
template<class T> struct Y<T*> { Y(T*); };
Y y{(int*) 0};

隐式生成的演绎指南可能需要通过类模板的特化来排序(作为决胜局)。

如果您想尝试原型(prototype)实现,作者已在 github 上发布了他们的 clang 分支:https://github.com/faisalv/clang/tree/clang-ctor-deduction .


论文中的讨论(“A note on injected class names”)表明注入(inject)类名优先于模板名;添加措辞以确保这一点:

The template-name shall name a class template that is not an injected-class-name.

关于c++ - 关于C++17中类模板参数推导的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363961/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com