3

我在这里重新发布一个comp.std.c++ Usenet 讨论,因为该组变得非常不可靠。我在那儿提交的最后几篇文章已经无效,活动几乎停止了。我怀疑我被禁止和/或其他人只是失去了兴趣。希望所有感兴趣的人都能找到这个讨论,并且会有一个普遍的迁移。也许那时他们会任命一位新的主持人。


你好!

根据我目前对条件运算符和 xvalues 的 N3126 草案的解释,我希望以下断言成立:

 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 说:

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

虽然,它并没有清楚地说明生成的 glvalue 指的是 glvalue 操作数所指的对象之一——或者这是暗示的,否则它会返回一个纯右值?在 C++0x 模式下使用 GCC 4.5.1,第二个断言失败。引用 k 似乎是指一些临时对象。如果冒号周围的两个操作数都是相同类型的 xvalue,有人可以澄清是否允许编译器创建这样的临时变量?

我目前假设 GCC 是错误的和/或就 xvalues 而言不是最新的。

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

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

应该屈服?使用 GCC 4.5.1,xvalue 变量被初始化为 false。这符合当前的标准草案吗?

TIA,塞巴斯蒂安

4

1 回答 1

2

我认为 GCC 4.5.1 不符合第 5.16/4 节。您是否提交了错误报告

无论如何,我认为它符合三元运算符代码。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 的类型;
  • 否则,decltype(e) 是 e 的类型。decltype 说明符的操作数是未计算的操作数(第 5 条)。

decltype通过获取适当的声明并从中返回所需的类型来工作。对于非重载运算符,它几乎没有智能。也许还有一点

  • 否则,如果e是 xvalue,则 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;
};
于 2010-10-11T20:46:27.190 回答