显然这应该有效:
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>;
虽然至少第一个代码片段起作用肯定是理想,但我还没有找到实际使在当前工作草案中工作的措辞。有谁知道它在哪里?
答案 0 :(得分:1)
这不是一个严格的答案,因为我认为这样的措辞实际上并不存在。这更像是与问题相关的信息的拼凑。
这是Core Issue 2。 Oulu和Issaquah关于此功能的讨论清楚地表明 intent 是通过typedef查看是有效的,但没有添加任何措辞来表明这应该如何工作 - 它只是。 ..是。措辞原样表明扣除指南:
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
答案 1 :(得分:0)
我认为仔细阅读会清楚说明:
函数参数的类型是构造函数的类型。
请注意C<T>::value_type
不是类型,而是typedef-name。由于替换,构造函数参数的类型为T
,而等效的演绎指南实际上是
template <class T> C(T) -> C<T>;
在您的示例中,使用C<T>::value_type
使得看起来很像非推断的上下文存在问题,但该问题实际上并不存在,因为扣除函数参数不涉及查找。