用户定义与自动模板扣除指南的优先级
User-defined vs automatic template deduction guides priorities
假设我们有一个类似的类,并带有用户定义的扣除指南:
template<typename T, typename... Args>
struct Foo
{
Foo(Args&&...) { std::cout << "just Args: " << __PRETTY_FUNCTION__ << std::endl; }
Foo(Args&&..., T&&) { std::cout << "Args and T: " << __PRETTY_FUNCTION__ << std::endl; }
};
template<typename... Args>
Foo(Args&&...) -> Foo<Void, Args...>;
现在,让我们尝试创建此类的实例:Foo foo { 10 };
。推导的模板参数是什么?
一些实验后,这取决于编译器。也就是说,GCC 7和Clang 6(来自中继线)似乎选择了自动指南,用int
和Args
用空包实例化T
,因此输出为
Args and T: Foo<T, Args>::Foo(Args&& ..., T&&) [with T = int; Args = {}]
另一方面,clang 5选择了用户定义指南:
just Args: Foo<Void, int>::Foo(Args &&...) [T = Void, Args = <int>]
在这种情况下,哪个选择是正确的选择,以及如何使用用户定义的扣除指南?
wandbox上的完整示例。
让我们从第一原则开始。尝试从Foo{10}
推导涉及在此集合上进行超载分辨率:
template <typename T, typename... Args>
Foo<T, Args...> __f(Args&&... ); // ctor #1
template <typename T, typename... Args>
Foo<T, Args...> __f(Args&&..., T&&); // ctor #2
template <typename... Args>
Foo<Void, Args...> __f(Args&&... ); // deduction guide
在第一个构造函数合成的函数中, T
是一个未建立的上下文。在第二个构造函数合成的函数中, Args
是未建立的上下文。所以也不可行。扣除指南是可行的,因此它是最好的可行候选人,因此我们最终获得了Foo<Void, int>
。
一旦我们在那里,我们将再次执行超负荷分辨率以选择构造函数。这更简单,第一个是可行的,第二个不可行,因此应调用。
任何其他行为都是编译器错误(已提交83447)。
相关文章:
- 带自定义比较器的最小优先级队列
- 优先级队列自定义比较器
- Cython中带有自定义比较器的优先级队列
- 具有自定义对象的C 优先级队列
- 用户定义与自动模板扣除指南的优先级
- 我正在声明一个自定义优先级队列,包括 pair<pair<int,int>int >,如何清除它?
- C++ 具有自定义比较函数的优先级队列在 push() 上行为不正确
- 通过引用传递自定义优先级队列
- 尝试使用自定义类的结构中的变量创建该类的优先级队列
- 使用自定义比较器声明C++优先级队列的问题
- 优先级队列自定义比较器的返回值表示什么
- 如何在 c++ 中定义具有四个值的优先级队列
- 访问类的私有成员的自定义优先级队列比较器
- C++类中具有自定义比较功能的优先级队列
- 如何在优先级队列中使用自定义类
- 用户定义类型的优先级队列
- 第二次推送时,优先级队列出现自定义比较器分段故障
- 为优先级队列的基础容器使用自定义类型的列表
- 在c++中使用用户定义对象的优先级时遇到问题
- 自定义类型的运算符优先级,以及当存在多个相同运算符时是否可能进行延迟求值