gpt4 book ai didi

c++ - 类模板的嵌套模板参数推导不起作用

转载 作者:IT老高 更新时间:2023-10-28 23:00:19 25 4
gpt4 key购买 nike

this Q&A我编写了一个小包装类,它提供对范围的反向迭代器访问,依赖于类模板的 c++1z 语言功能模板参数推导(p0091r3p0512r0)

#include <iostream>
#include <iterator>
#include <vector>

template<class Rng>
class Reverse
{
Rng const& rng;
public:
Reverse(Rng const& r) noexcept
:
rng(r)
{}

auto begin() const noexcept { using std::end; return std::make_reverse_iterator(end(rng)); }
auto end() const noexcept { using std::begin; return std::make_reverse_iterator(begin(rng)); }
};

int main()
{
std::vector<int> my_stack;
my_stack.push_back(1);
my_stack.push_back(2);
my_stack.puhs_back(3);

// prints 3,2,1
for (auto const& elem : Reverse(my_stack)) {
std::cout << elem << ',';
}
}

但是,执行 Reverse 的嵌套应用程序不会产生原始的迭代顺序

// still prints 3,2,1 instead of 1,2,3
for (auto const& elem : Reverse(Reverse(my_stack))) {
std::cout << elem << ',';
}

Live Example (g++ 7.0 SVN 和 clang 5.0 SVN 的输出相同)

罪魁祸首似乎是类模板的模板参数推导,因为通常的包装函数确实允许正确嵌套

template<class Rng>
auto MakeReverse(Rng const& rng) { return Reverse<Rng>(rng); }

// prints 1,2,3
for (auto const& elem : MakeReverse(MakeReverse(my_stack))) {
std::cout << elem << ',';
}

Live Example (g++ 和 clang 的输出相同)

问题:类模板的嵌套模板参数推导是否应该只工作“一层”深,或者这是 g++ 和 clang 的当前实现中的错误?

最佳答案

这可以在 [over.match.class.deduct]/p1 中解释。 :

A set of functions and function templates is formed comprising:

  • For each constructor of the class template designated by the template-name, a function template with the following properties:
  • The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.

  • The types of the function parameters are those of the constructor.

  • The return type is the class template specialization designated by the template-name and template arguments corresponding to the template parameters obtained from the class template.

我的理解是编译器发明了以下两个函数(两个——包括为这个类隐式生成的复制构造函数):

template <typename Rng>
Reverse<Rng> foo(const Rng& r); // #1

template <typename Rng>
Reverse<Rng> foo(const Reverse<Rng>& r); // #2

然后尝试根据调用选择最佳重载:

foo(Reverse<std::vector<int>>(my_stack));

解析为#2,因为这个更专业。结论是:

Reverse(Reverse(my_stack))

涉及一个复制构造函数来构造外部 Reverse 实例。

关于c++ - 类模板的嵌套模板参数推导不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42244250/

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