用户可否参考推导式的推导?

Can a user refer to a deduced type of a deduction guide?

提问人:Fureeish 提问时间:1/9/2023 更新时间:1/10/2023 访问量:86

问:

std::basic_string演绎指南允许用户在不指定其模板参数的情况下使用名称。用户还可以创建自己的扣除指南。假设用户想要重新创建 。他们迟早会负责实施扣除指南。但是,cppreference 的注释让我想知道这是否可能。有问题的注释说:std::basic_stringstd::basic_string

提供这些扣除指南是为了允许从 .(3)中的参数类型是指推导引板推导的类型的杆件类型。仅当 Alloc 满足 Allocator 时,这些重载才会参与重载解决。std::basic_stringstd::basic_string_viewsize_typesize_type

强调我的。

用户能否实现这样的要求?程序员如何引用推导类型的别名?

C++ 演绎指南

评论

0赞 AndyG 1/9/2023
如果要为某个类编写演绎指南,它必须与定义该类位于同一命名空间中。如果该命名空间是 ,那么您经常会遇到标准合规性问题,因为大多数*时间不允许在那里添加任何内容。std
0赞 Fureeish 1/9/2023
@AndyG我不想扩展任何相关内容。我知道向命名空间添加演绎指南是 UB。我只是从类型的演绎指南要求中汲取灵感,并想知道是否可以将它们应用于用户定义的类型。std::stdstd

答:

0赞 Marek R 1/9/2023 #1

首先,请参阅有关用户定义的扣款指南的文档。

然后看看这个例子:

#include <iostream>
#include <string>
#include <vector>

template<typename T>
class Foo
{
public:
    template<typename C>
    Foo(C) {}

    template<typename C>
    Foo(C, typename C::size_type) {}
};

template<typename C>
Foo(C) -> Foo<typename C::value_type>;

template<typename C>
Foo(C, typename C::size_type) -> Foo<typename C::value_type>;

int main()
{
    std::string s;
    std::vector v{1, 3, 1};

    Foo foo{s}; // Here Foo<char> is used
    static_assert(std::is_same_v<Foo<char>, decltype(foo)>);

    Foo bar{v};
    Foo baz{v, 2};
    static_assert(std::is_same_v<Foo<int>, decltype(bar)>);
    static_assert(std::is_same_v<Foo<int>, decltype(baz)>);
}

https://godbolt.org/z/fsd6aMnY4

如您所见,类型用于引导实际所需的类型。 您可以使用更复杂的东西。CFoo<typename C::value_type>

评论

2赞 Nicol Bolas 1/9/2023
这没有抓住重点。所需的推导指南看起来更像是这样:它必须使用推导的模板作为参数的一部分。Foo(C, Foo<typename C::value_type>::some_type) -> Foo<typename C::value_type>;
0赞 Caleth 1/9/2023
@NicolBolas虽然你可以这样做
0赞 Nicol Bolas 1/10/2023
@MarekR:不是; (我说错了)。关键是被推导的类 () 也是类型参数名称的一部分。C::value_typeFoo<C>::value_typeFoo<C>
0赞 Marek R 1/10/2023
@NicolBolas问题是这个问题不是很明确。现在,我后悔在回答之前删除了我在问题下的评论,请求他希望添加此扣除指南的代码。我认为在我的表格或您的表格中添加扣除指南没有问题。这是一个问题,最终目标是什么。
0赞 Nicol Bolas 1/10/2023
@MarekR:我认为你对这个问题想得太多了。问题在于,字面文本的答案是如此明显,以至于你认为它一定不止于此。但事实并非如此。OP 根本没有尝试过明显的解决方案。
2赞 Artyer 1/10/2023 #2

“由演绎指南推导的类型”只是右边的类型:->

template< class CharT,
          class Traits,
          class Alloc = std::allocator<CharT>> >
basic_string( std::basic_string_view<CharT, Traits>, typename basic_string<CharT, Traits, Alloc>::size_type,
              typename basic_string<CharT, Traits, Alloc>::size_type, const Alloc& = Alloc() )
    -> basic_string<CharT, Traits, Alloc>;

似乎它只是再次编写所有模板参数的简写,尤其是在推导出的类型会长得多的地方,例如 unordered_set<typename std::iterator_traits<InputIt>::value_type, std::hash<typename std::iterator_traits<InputIt>::value_type>, std::equal_to<typename std::iterator_traits<InputIt>::value_type>,Alloc>