为什么在for循环中两个逗号分隔的语句之间要加(void)?(涉及IT技术)

15

以下代码来源于 cppreference.comstd::lexicographical_compare 的实现示例:

template<class InputIt1, class InputIt2>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1,
                             InputIt2 first2, InputIt2 last2)
{
    for ( ; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2 ) {
        if (*first1 < *first2) return true;
        if (*first2 < *first1) return false;
    }
    return (first1 == last1) && (first2 != last2);
}

为什么循环里有一个(void),如果不加上它会有什么后果?


有人计划在++first1之前添加(void),因为++first1,(void) ++first2仍可能实例化某些在其他地方声明的operator,这可能仍然会造成问题。 - cpplearner
@cpplearner 某人,嗯? - T.C.
2个回答

25

如果InputIt1类型的前缀递增运算符返回值类型有重载逗号运算符,那么表达式++first1, ++first2可能会调用它。因此,将++first2的结果强制转换为void可以确保不会调用重载逗号运算符,因为重载逗号运算符不能接受void作为参数。


1
疯狂的语言规范得到确认。有人真正看到过过载的合法使用吗? - Passer By
2
@路人甲 ::boost::assign - user7860670
啥?怎么用啊?刚刚看了看 boost::assign。 - Passer By
1
@PasserBy using namespace boost::assign; vector<int> v; /* ... */ v += 1, 2, 3, 4, 5, 6, 7, 8, 9; 这段代码将这些值添加到了 v 的末尾。 - user7881131
2
@路人甲 https://github.com/facebook/folly/blob/master/folly/Expected.h#L556 - cpplearner

6
这似乎是一个偏执的实现者,因为他们不知道他们正在处理的类型的确切细节,所以他们需要涵盖所有可能性。
您可能已经知道,operator,可以用于类型重载。因此,在使用类似++first1,++first2或仅仅是first1,first2这样的语句时,可能会产生意想不到的后果。
(void)强制转换被放在那里,以便任何重载的operator,都不能生效,因为运算符无法操作不完整的void类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接