使用使用成员类型别名的构造函数来推论类模板参数

Deducing class template arguments with a constructor that uses a member type alias

本文关键字:参数 构造函数 成员类 成员 类型 别名      更新时间:2023-10-16

所以显然应该有效:

template<class T>
struct C {
   using value_type = T;
   C(value_type);
};
C c(1); // C<int>

也是如此(请参阅[over.match.class.deduct]/3中的B示例(:

template<class T>
struct D {
   template<class> using meow_t = T;
   template<class U>
   D(U, meow_t<U>);
};
D d(1, 'c'); // D<char>

请注意,看似等效的显式指南无法正常工作,因为该参数是一个未划分的上下文:

template<class T>
C(typename C<T>::value_type) -> C<T>;

虽然至少是第一个摘要作品,但

肯定是理想的,但我还没有找到真正在当前工作草案中使用的措辞。有人知道它在哪里吗?

这不是一个严格的答案,因为我认为这种措辞实际上并不存在。这更多地是将与问题相关的信息拼凑在一起。


这是核心问题2。关于此功能的Oulu和Issaquah的讨论明确表明, Intent 是通过Typedefs查看是有效的,但是没有添加的措辞来指示如何表明这应该有效 - 只是...是。措辞AS建议:

的扣除指南
template<class T>
struct C {
   using value_type = T;
   C(value_type);
};

将是:

template <class T> C<T> foo(typename C<T>::value_type );

这将是一个未造成的上下文,而失败的情况,但是[thread.lock.guard]没有针对这种情况的明确扣除指南。

[over.match.best]中的示例显然是为了表明Typedef应该可以起作用,尽管该示例中没有任何示例实际上使用#1作为扣除指南:

template <class T> struct A {
  using value_type = T;
  A(value_type);    // #1
  A(const A&);      // #2
  A(T, T, int);     // #3
  template<class U>
    A(int, T, U);   // #4
  // #5 is the copy deduction candidate, A(A)
};
A x(1, 2, 3);       // uses #3, generated from a non-template constructor
template <class T>
A(T) -> A<T>;       // #6, less specialized than #5
A a(42);            // uses #6 to deduce A<int> and #1 to initialize
A b = a;            // uses #5 to deduce A<int> and #2 to initialize
template <class T>
A(A<T>) -> A<A<T>>; // #7, as specialized as #5
A b2 = a;           // uses #7 to deduce A<A<int>> and #1 to initialize

我认为仔细阅读使此清晰:

函数参数的类型是构造函数的类型。

请注意,C<T>::value_type不是类型,它是Typedef-name。由于替换,构造函数参数的类型为 T,等效扣除指南实际上是

template <class T> C(T) -> C<T>;

在您的示例中,使用C<T>::value_type使其似乎很喜欢存在非伪造上下文的问题,但是实际上并不存在该问题,因为扣除函数参数不涉及查找。