Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用使用成员类型别名的构造函数推断类模板参数_C++_Language Lawyer_C++17 - Fatal编程技术网

C++ 使用使用成员类型别名的构造函数推断类模板参数

C++ 使用使用成员类型别名的构造函数推断类模板参数,c++,language-lawyer,c++17,C++,Language Lawyer,C++17,所以很明显,这应该是可行的: template<class T> struct C { using value_type = T; C(value_type); }; C c(1); // C<int> 请注意,似乎等效的显式指南不起作用,因为参数是非推断上下文: template<class T> C(typename C<T>::value_type) -> C<T>; 模板 C(typename C::va

所以很明显,这应该是可行的:

template<class T>
struct C {
   using value_type = T;
   C(value_type);
};

C c(1); // C<int>
请注意,似乎等效的显式指南不起作用,因为参数是非推断上下文:

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

虽然至少第一个代码片段能够工作确实是可取的,但我还没有找到在当前的工作草案中真正起作用的措辞。有人知道它在哪里吗?

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


这是。在Oulu和Issaquah中关于此功能的讨论清楚地表明,其目的是查看typedefs是有效的,但是没有添加任何措辞来说明这应该如何工作-它只是。。。是目前的措辞表明,扣除指南适用于:

template<class T>
struct C {
   using value_type = T;
   C(value_type);
};
模板
结构C{
使用值_type=T;
C(价值型);
};
将是:

template <class T> C<T> foo(typename C<T>::value_type );
模板C foo(typename C::value\u type);
这将是一个非推断的背景和失败,但没有一个明确的演绎指南的情况下

中的示例显然旨在表明typedef应该起作用,尽管该示例中没有一个示例实际使用#1作为推断指南:

模板结构A{
使用值_type=T;
A(值_类型);/#1
A(常数A&)/#2
A(T,T,int);/#3
模板
A(int,T,U);/#4
//#5为复印件扣款候选人,A(A)
};
A x(1,2,3);//使用从非模板构造函数生成的#3
模板
A(T)->A;//#6,专业程度低于#5
A(42);//使用#6推导A,使用#1初始化
A b=A;//使用#5推导A,使用#2初始化
模板
A(A)->A;//#7,像#5一样专业
A b2=A;//使用#7推导A,使用#1初始化

我认为仔细阅读可以清楚地看出:

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

请注意,
C::value_type
不是一个类型,而是一个typedef名称。由于替换,构造函数参数的类型是
T
,而等效的推导指南实际上是

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

在您的示例中,使用
C::value\u type
使非推断上下文似乎存在问题,但该问题实际上并不存在,因为没有涉及推断函数参数的查找。

无关:不应
d(1,“C”)
抛出一个类似于
为参数“T”(“int”和“char”)推断出冲突类型的错误。
?或者这里
meow\t
是在一个非推断的上下文中?但是如果是,那么代码中的注释是错误的,
//D
应该是
//D
。否
meow\u t
t
。对,我就是这么想的。但是在
d(1,'c')
中有一个
int
和一个
char
。为什么类型推断在这里可以工作,因为(afaik)没有执行转换?例如,这个C++1z之前的示例没有编译:再看一遍,它是
t
,而不是
U
。哦,是的,谢谢,我的错!不过,这并不完全是CWG2。演绎向导不是成员,由它们合成的函数/函数模板也不是原始类模板的成员。@t.C.是的,不完全是,但它在同一轨道中。我怀疑这只会增加标准中未充分保密的模板相关问题的数量。@T.C.想在std讨论中加入一些东西吗?我相信我们在Issaquah讨论中描述的方式是“这里发生了激烈的手工操作”。预期的规则是CWG2:如果您可以通过仅使用模板中的信息来确定类型是什么,那么您可以针对该类型。(换句话说,如果使用可推断类型重新声明构造函数是有效的,则可以根据该类型进行推断。但这会让您返回CWG 2以确定重新声明何时有效。)相同的参数适用于
T
:“它是一个typedef名称”(请参见[temp.param]/3);它“不是一种类型”。我不明白你如何根据这个论点在这里做出原则性的区分。我明白你的观点,但这是我能从代码中得到的最接近的。使用
value\u type
没有那么接近,它会导致一个问题,它看起来像是一个非推断上下文,实际上并不相关,因为不涉及查找。与其他任何情况不同,所讨论的构造函数是类模板的成员,而不是类(例如,类模板专门化)。其参数类型为
T
,因为尚未提供
T
的值。是的,这是一个丑陋的语言黑客。
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
template <class T> C(T) -> C<T>;