【问题标题】:Arithmetic operation with a void?带空格的算术运算?
【发布时间】:2014-03-20 07:30:59
【问题描述】:

如果可能的话,我知道以下做法绝对是一种糟糕的做法,但我想知道这是否可行。

问题如下:是否有可能在 C++ 中(并且以某种方式编译器不会抛出任何警告)对返回 void 的函数执行无用的算术运算。

std::vector<int> v;
int i = 42 + v.resize(42); 
/* How to transform the last line to execute resize and to have i = 42 */

我知道这很愚蠢,但这不是问题......

【问题讨论】:

  • 没有测试,没有提交作为答案,但也许... int i = 42 + (v.resize(42) || 0);
  • @isick C++ 不是 JavaScript ;-P
  • 哈哈,显然我已经不在我的元素了。应该把它留给 C++ 专家。很高兴得到答复
  • 这很愚蠢。 void() 不为零!
  • 你为什么要问?它是生成的代码,还是在某个宏内部?

标签: c++ c++11 void arithmetic-expressions


【解决方案1】:

我不确定这是否有意义,但您可以在此处使用comma operator

int i = (v.resize(42), 42);

【讨论】:

  • , 可能有充分的理由使用逗号运算符 , 但这不是 , 一个 ,, 他们。
  • @Yakk:你为什么认为它不是逗号运算符的好用例(想象一下它在模板、宏或某些生成的 C++ 代码中)?当然,作为手写代码,它很糟糕,因为可读性不强。
  • 在模板中,多行执行——没有限制。在宏中,调用一个函数。在生成的代码中,调用一个函数。在生成的代码和宏中,您都可以在远离使用点的地方使用辅助内容,例如:template&lt;typename C&gt; std::size_t set_container_size( C&amp; c, std::size_t s ) { c.resize(s); return s; },然后是int i = set_container_size(v, 42);在宏中 或生成的代码。 “好”用法的一个示例:for 限制(增加两个变量)和 pre-C++1y constexpr 体操。
【解决方案2】:

你可以使用comma operator:

int i = (v.resize(42), 42);

并且使用 GCC 你可以使用它的statement expression 扩展:

int i = ({v.resize(42); 42;})

在标准C++11 中,您可以使用和调用匿名closure

int i = ([&v]() {v.resize(42); return 42;}());

【讨论】:

  • [&amp;]{ code } 可能是合理的,而不是 [&amp;v](){ code }。并不是说它比,好多了!
【解决方案3】:

类型 void 没有值,因此它不能用于算术表达式。

在我看来,成员函数resize 的设计很糟糕。而不是voidit 应该返回对象本身。在这种情况下,您可以编写例如

int i = v.resize(42).size(); 

我在讨论 C++ 标准的论坛中指出了这一点。

至于你的问题,你可以写

int i = ( v.resize(42), v.size() );

使用逗号运算符。

或者将这两个调用分开会更好

v.resize(42);
int i = v.size();

【讨论】:

  • 恕我直言,GCC的语句表达式扩展应该已经添加到标准中。
【解决方案4】:

不明白重点,但这是另一种方式

std::tie(i, std::ignore) = std::make_tuple(42, (v.resize(42),1) );

你也可以这样做:

if ((i=42)) v.resize(42); 

别忘了

do { v.resize(42); } while (!(i=42)); 

还有最喜欢的

(i=42) ? v.resize(42) : i;

或者(帖子中唯一的严肃的c++

int i(0);
std::vector<int> v(i=42);

来吧,这没有尽头

.....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    相关资源
    最近更新 更多