【问题标题】:why would I call a function with the function name wrapped in parens?为什么我要调用一个函数名用括号括起来的函数?
【发布时间】:2016-07-21 23:42:28
【问题描述】:

我最近遇到了如下代码:

void function(int a, int b, int c){
  //...
}

int main(){
  //...
  (function)(1,2,3);
  //...
}

将函数名称单独包装在括号中的意义何在?
它是否有任何与function(1,2,3); 不同的影响?

为什么语言允许这样的语法?

【问题讨论】:

  • 它对任何输出/返回有什么影响吗?
  • @FirstStep,我无法运行实际代码。我上面的内容是人为的,但我正在寻找任何(func)(arg)与func(arg)不同的例子。有范围的东西?命名空间?查找分辨率?该函数本身不是宏。也许这只是一个错字。

标签: c++ function syntax parentheses function-call


【解决方案1】:

我能想到的唯一情况是function 被定义为宏。

在 C 中,标准库函数也可以实现为类似函数的宏(为了提高效率)。将函数名括在括号中调用实际函数(因为函数名后面没有()。

至于为什么语言允许这种语法,函数调用由指向函数类型的表达式和括号中的参数组成。在大多数情况下,前缀是函数名(隐式转换为指向函数的指针),但它可以是任意表达式。 任何表达式都可以用括号括起来,通常不会改变其含义(除了影响优先级)。 (但请参阅 Jonathan Leffler 的 cmets 以获得一些反例。)

【讨论】:

  • 在“Effective Modern C++”中,Scott Meyers 说:“在int x = 0; 中,x 是一个变量的名称,所以decltype(x)int。但是将名称 x 括在括号中——“(x)”——会产生比名称更复杂的表达式。作为一个名称,x 是一个左值,C++ 也将表达式 (x) 定义为一个左值。因此decltype((x))int&。在名称周围加上括号可以更改 decltype 为其报告的类型! ... C++14 对 decltype(auto) [...] 的支持意味着您编写 return 语句的方式中看似微不足道的更改可能会影响函数的推导类型”
  • 本书接着给出了两个例子:decltype(auto) f1() { int x = 0; … return x; // decltype(x) is int, so f1 returns int }decltype(auto) f2() { int x = 0; … return (x); // decltype((x)) is int&, so f2 returns int& } 这主要是仅供参考——但我发现它非常有趣,而且出乎意料。在一些不寻常的情况下,它会稍微修改你所说的内容。
  • @JonathanLeffler:添加了黄鼠狼的话。
【解决方案2】:

除了抑制类似函数的宏扩展外,还可以在括号 suppresses argument-dependent lookup 中包裹一个不合格的函数名称。例如:

namespace meow {
    struct kitty {};
    void purr(kitty) {}
}

int main() {
    meow::kitty stl;
    purr(stl); // OK, ADL finds meow::purr
    (purr)(stl); // error; no ADL is performed
}

【讨论】:

    猜你喜欢
    • 2011-08-14
    • 2013-06-16
    • 2012-02-21
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    相关资源
    最近更新 更多