为什么我不能直接在临时对象上调用operator()?

16

我想做的事情可以总结为以下代码:

struct A{};

struct B{
    A& a;
    B(A& a) noexcept : a(a){}
    int operator()(int) {}
};

int main(){
    A a;
    B(a)(2);
}

我的编译器(g++ 6)拒绝了这段代码,抱怨a遮蔽了参数。但是,如果我尝试显式调用operator(),它正常工作。

看起来,g++会忽略括号,并将语句视为声明。

这是指定的或预期的行为吗?


@Bathsheba,老实说,这是从我的现有代码中提取出来的,它是一个共享库,所以我真的不想在主函数中做任何事情... - YiFei
2
@YiFei 当然可以,但最好在你的问题中提供一个代码,这样我们就可以直接复制粘贴并测试你的代码。 - TartanLlama
2
@TartanLlama 好的,把f重写为main了。感谢你的建议。 - YiFei
2
@Bathsheba "超出我的薪资等级" 我并不那么确定.. - Hatted Rooster
我也不是![占位符] - TartanLlama
显示剩余4条评论
1个回答

23
这是一条棘手的解析规则,有时会让你措手不及。正如您所建议的那样,B(a)(2);实际上等同于B a(2);,因此您的代码尝试使用int初始化B
为了解决这个问题,您可以使用C++11的统一初始化方式:
B{a}(2);

3
或者 (B(a))(2); - Christian Hackl
我会避免使用 operator()... 非常感谢。 - YiFei
4
如果某个语句“看起来像”是一个声明语句,那么它就是一个声明语句。对于模棱两可的语句解析,会被视为声明语句而非表达式。 - MSalters
最令人烦恼的解析。附带说明。 - Hatted Rooster
@YiFei:一开始看起来并不是很易读,对吧?而且为什么要使用运算符重载呢?它的唯一目的是使代码更易读,但实际上却产生了相反的效果。 - Christian Hackl
@ChristianHackl 是的,当然,我会使用一些命名方法。谢谢。 - YiFei

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