2010-10-11 100 views
3

我在此处重新发布comp.std.c++ Usenet discussion,因为该组已变得非常不可靠。我在那里提交的最后几篇帖子已经进入空白,活动几乎停止。我怀疑我被禁止了,或者其他人都失去了兴趣。希望所有感兴趣的人都能找到这个讨论,并且会有一个全面的移民。也许他们会任命一位新的主持人。C++ 0x:条件运算符,xvalues和decltype


您好!

用我目前的草案N3126 w.r.t.条件 操作者和xvalues,我期望以下断言持有:

int i = 0; 
int& j = true? i : i; 
int&& k = true? std::move(i) : std::move(i); // #2 
assert(&i == &j); // Holds since C++98 
assert(&i == &k); // Should this hold as well? 

5.16/4表示:

如果第二和第三个操作数[给 条件运算符]是 glvalues相同的值的类别 并具有相同类型,则结果是,类型和值的类别 [...]

虽然它并没有明确说明所得到的glvalue是指 glvalue操作数引用的对象之一 - 或者这是暗示的 ,否则它会返回一个prvalue?在C++ 0x模式下使用GCC 4.5.1 ,第二个断言失败。参考k似乎是 引用了一些临时对象。如果冒号周围的两个操作数 都是相同类型的xvalues,是否有人可以澄清是否允许 comiler创建这样的临时文件?

我目前假设GCC是buggy和/或不是最新的方面 xvalues。

后续问题是:能够检测表达式的值类别 不是很好吗?如果我们忽略条件运算符 ,我们可以用decltype检测表达式的值类别。但是 什么是

bool xvalue = std::is_rvalue_reference< 
    decltype(true ? std::move(i) : std::move(i)) >::value; 

应该会产生?使用GCC 4.5.1,xvalue变量被初始化为 ,并且为false。这是否符合当前的标准草案?

TIA, 塞巴斯蒂安

+0

我想你的意思[comp.std.C++],通过你的链接所暗示的。是的,它确实有一些滞后时间,但我想你可能刚刚遇到最近的谷歌停电事件。您是否通过Google网上论坛发布? – 2010-10-11 20:41:30

+0

@Alf:我是通过Google网上论坛发布的,但是不会影响所有组?自9月以来,comp.std.C++几乎没有任何活动,对于未经审查的组而言并非如此。 – Potatoswatter 2010-10-11 20:48:36

+0

从这里c.l.C++在我的本地“today”中有30个帖子,c.s.C++有两个(其中一个来自“SG”,其中一个似乎是你),另外五个消息来自本月其他人。 – sbi 2010-10-11 20:49:03

回答

2

我觉得GCC 4.5.1是不合格WRT§5.16/ 4。你有filed a bug report吗?

无论如何,我认为它符合那个三元操作符代码。 decltype由§7.1.6.2/ 4定义:

通过decltype(e)中表示的类型是被定义为 如下:

  • 如果e是一个括号的ID-表达或类成员访问 (5.2.5),decltype(e)是由e命名的实体的类型 。如果没有这样的实体,或者如果e名称是一组重载函数,则该程序是 不合格;
  • 否则,如果e是一个函数调用(5.2.2)或 重载操作的调用(括号 周围e为忽略),decltype(e)中 静态 选择的函数的返回类型;否则,如果e是左值,则decltype(e)是T &,其中T是e的类型 ;如果e是左值,则decltype(e)是T &,其中T是e的类型 。
  • 否则,decltype(e)是e的类型。 decltype 说明符的操作数是未评估的操作数 (第5章)。

decltype作品通过取得适当的声明,并从它返回所希望的类型。对于非重载操作符来说,它几乎没有智能。也许另一点

  • 否则,如果e是一个x值,decltype(e)是T&&,其中Te

类型将是顺序,特别是因为,如写入,xvalues得到视为价值。此外,您的表达式与std::common_type(§20.7.6.6/ 3)的定义完全一致。

一个简单的解决办法(套用一句话:VP):

template< typename T1, typename T2 > 
struct common_type_and_category { 
    typedef typename std::conditional< 
     std::is_same< T1, T2 >::value, 
     T1, 
     typename std::common_type< T1, T2 >::type 
    >::type type; 
};