Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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
这是为什么;";cpp模板下一个出现故障? 我在这里阅读了这个代码> MIN 模板,作为一个例子,详细说明C++代码如何与Python代码进行比较。 template <class T, class U> auto min(T x, U y)->decltype(x < y ? x : y) { return x < y ? x : y; } 模板 自动最小值(tx,uy)->decltype(x_C++_C++11_Decltype - Fatal编程技术网 MIN 模板,作为一个例子,详细说明C++代码如何与Python代码进行比较。 template <class T, class U> auto min(T x, U y)->decltype(x < y ? x : y) { return x < y ? x : y; } 模板 自动最小值(tx,uy)->decltype(x,c++,c++11,decltype,C++,C++11,Decltype" /> MIN 模板,作为一个例子,详细说明C++代码如何与Python代码进行比较。 template <class T, class U> auto min(T x, U y)->decltype(x < y ? x : y) { return x < y ? x : y; } 模板 自动最小值(tx,uy)->decltype(x,c++,c++11,decltype,C++,C++11,Decltype" />

这是为什么;";cpp模板下一个出现故障? 我在这里阅读了这个代码> MIN 模板,作为一个例子,详细说明C++代码如何与Python代码进行比较。 template <class T, class U> auto min(T x, U y)->decltype(x < y ? x : y) { return x < y ? x : y; } 模板 自动最小值(tx,uy)->decltype(x

这是为什么;";cpp模板下一个出现故障? 我在这里阅读了这个代码> MIN 模板,作为一个例子,详细说明C++代码如何与Python代码进行比较。 template <class T, class U> auto min(T x, U y)->decltype(x < y ? x : y) { return x < y ? x : y; } 模板 自动最小值(tx,uy)->decltype(x,c++,c++11,decltype,C++,C++11,Decltype,起初这看起来很无辜,但达维德·范德沃德说了这句话 在其返回类型规范中使用decltype的min模板不起作用:它返回一个引用(因为参数是左值),该引用在大多数常用情况下都指向局部变量 我想可能不是每个人都清楚这个问题是如何表现出来的。你能给出详细的解释和可能的修复方法吗?rev 3:KonradRudolph template <class T, class U> auto min(T x, U y) -> typename std::remove_reference<d

起初这看起来很无辜,但达维德·范德沃德说了这句话

在其返回类型规范中使用decltype的min模板不起作用:它返回一个引用(因为参数是左值),该引用在大多数常用情况下都指向局部变量

我想可能不是每个人都清楚这个问题是如何表现出来的。你能给出详细的解释和可能的修复方法吗?

rev 3:KonradRudolph

template <class T, class U>
auto min(T x, U y) -> typename std::remove_reference<decltype(x < y ? x : y)>::type
{ 
    return x < y ? x : y; 
}
模板
自动最小值(tx,uy)->typename std::remove\U reference::type
{ 
返回x
第2版:肯尼特

template <class T, class U>
auto min(T x, U y)->decltype(x < y ? std::declval<T>() : std::declval<U>())
{ 
    return x < y ? x : y; 
}
模板
自动最小值(tx,uy)->decltype(x
版本1:T和U必须是默认可构造的

template <class T, class U>
auto min(T x, U y)->decltype(x < y ? T() : U())
{ 
    return x < y ? x : y; 
}
模板
自动最小值(tx,uy)->decltype(x
测试:

intmain()
{
int x;int y;
静态断言(std::is_same::value,“”);
返回0;
}
编辑:


我有点惊讶,但它实际上是用remove_引用编译的。

参数是按值传递的(
T
U
被推断为
int
),但是
的类型?:
表达式在这种情况下被推断为引用,因为它们是函数内部的局部左值。具体内容将在几分钟后@Johannes的回答中给出:问题是这些参数没有被当作参考。对于多态类型,这将调用切片,然后调用对局部变量的引用返回。解决方案是将参数作为右值引用,调用完美转发,然后简单地推导并返回返回类型。完成此操作后,返回一个引用就可以了,因为该值仍然存在。

有什么大惊小怪的,为什么没有人尝试显而易见的解决方案,即完美的转发

template <class T, class U>
typename std::enable_if< ! std::is_integral< T >() || ! std::is_integral< U >(),
                         typename std::common_type< T, U >::type >::type
min(T &&x, U &&y)
    { return x < y ? std::forward< T >( x ) : std::forward< U >( y ); }

template <class T, class U>
decltype( typename std::enable_if< std::is_integral< T >() && std::is_integral< U >(),
                         decltype( typename std::common_type< T, U >
         ::type{ U( -1 ) } ) >::type{ T( -1 ) } )
min(T &&x, U &&y)
    { return x < y ? std::forward< T >( x ) : std::forward< U >( y ); }
模板
typename标准::如果<,则启用!std::is_integral()|| |!std::is_integral(),
typename std::common_type::type>::type
最小值(T&x、U&y)
{返回x(x):std::forward(y);}
模板
decltype(如果()&&std::is_integral(),则typename std::enable_),
decltype(typename std::common_type
::类型{U(-1)}>::类型{T(-1)})
最小值(T&x、U&y)
{返回x(x):std::forward(y);}
现在,它的工作原理就像将表达式放入调用函数中一样,这正是用户所期望的(而且是总体上最好的)


编辑:根据霍华德的论文,现在它禁止危险的无符号与有符号操作,因为如果两个操作数都是整数类型,则要求从每个操作数类型到结果类型的转换为非狭义。但是,GCC不会编译这个,抱怨“
对不起,未实现:损坏构造函数”
“如果函数签名中以任何方式使用统一初始化,这似乎会发生。

通过引用返回有时可能是一个特性,而不是一个bug。稍后我们将回到这个话题。首先回顾一下基本知识:

int x; int y;
x    // this is an lvalue
y    // lvalue also
x+y  // not an lvalue - you couldn't do (x+y) = 3
x<y?x:y // lvalue - you can do (x<y?x:y) = 0

我们有一个决定要做。如果
min
的参数是引用,我们可能希望min返回引用。我想这多少是个品味的问题。如果你只想返回非引用,这很容易通过
std::remove_reference
decltype周围强制执行(我现在在等你发布答案,请参见:)我有点好奇如果T和U是不同的类型会发生什么?这行得通吗?@ronag:如果它们可以转换成一个共同的“基地”:float和int都应该可以转换为float,这将是表达式的类型。因此,对于我们这些没有真正了解细节的人(例如@potatostater中的代码对我来说太复杂了),我们应该写什么呢?只有一个模板参数的
min
函数(即没有计算返回类型的技巧)?对于C++03,该模板可用于计算返回类型:)否,
T
U
将是
int
。Xeo:是的,你是对的。我几乎自相矛盾的原因和解决办法。我已经更改了我的答案。这当然要求
T
U
是默认可构造的。难道我们不能使用对某个
id
函数的调用来从
x
y
获取一个临时值来强制使用非引用吗…或者只是
remove_reference
…@KonradRudolph:
std::declval()
@KennyTM,但它返回一个右值引用,因此我们遇到了与以前相同的问题,不是吗?我只是感到困惑:(我不知道这一切背后的棘手规则。@Johannes:当然。我相信每个人都会相信你不知道。)为什么推断为参考?下一个代码说没有空f2(整数x,长y){cout@yola,这是因为
int
long
是完全不同的类型。没有一个引用类型可以链接到这两个类型。但是如果x和y是相同的整数类型,那么它将是一个引用。+1是正确的想法-我想第一个句子不缺少否定。我不同意。问题是通过refere返回nce,因为这样您就可以执行:
float&f=std::min(3.0f,1);
这是不正确的。@Matthieu:@Matthieu:不,你不能这样做,因为
?:
当它的两个参数都是右值时,它的结果是右值。@DaveAbrahams:但不尝试返回引用是错误的。你应该能够执行类似
std::min(a,b)的操作=5;
if
a
bint x; int y;
x    // this is an lvalue
y    // lvalue also
x+y  // not an lvalue - you couldn't do (x+y) = 3
x<y?x:y // lvalue - you can do (x<y?x:y) = 0
int m = 5; int n = 10;
min(m,n) = 0; // do you want this to work?
int p = min(5,8); // reading from a now-invalid reference.
// Desired behaviour
int m = 5;
int n = 10;
min(3,7); // return by value. i.e. return an int
min(m,n); // return an int& which maps to either m or n
min(3,n); // return by value
min(foo(), bar()) // what makes sense here?