在逗号分隔的列表中使用 `void()` 的用法?

37

我在查看别人编写的代码时,看到了这个:

a(), void(), b();

其中 ab 都是一个自定义模板类的实例,该类旨在通过重载返回调用实例本身的 operator() 来像函数一样运作。

类的部分内容:

template <typename T>
class SomeClass{
    public:
    SomeClass& operator()(void);
    const SomeClass& operator()(void) const;
}

两个重载函数的返回语句如下:

template <typename T>
SomeClass<T>& SomeClass<T>::operator()(void){
    // do stuff
    return *this;
}

template <typename T>
const SomeClass<T>& SomeClass<T>::operator()(void) const{
    // do stuff
    return *this;
}

它们之间的 void() 是什么作用?我感到很奇怪。


8
如果没有更多的上下文,就无法给出权威的答案。C++ 的语法相当复杂。例如,“X *p” 可能意味着乘法,也可能是一个指针声明。您需要提供更多上下文信息。 - Sam Varshavchik
2
迄今为止,评论中有很多废话。评论不是用来猜测答案的。正确答案如下。 - Bathsheba
2
这是一个有效的问题,不应该被投票降低。 - Simple
3
实际上,@Bathsheba,鉴于发布的额外背景信息,下面的答案是不正确的。 - Sam Varshavchik
3
发贴的代码中,void()在哪里? - n. m.
显示剩余3条评论
1个回答

47

void()可以防止调用重载的operator(其中一个参数的类型为SomeClass<T>),因为这样的重载不能有void类型的参数。

您最常见到的是在模板中使用,用于可变参数包扩展:

// C++11/14:
int unpack[] = {0, (do_something(pack), void(), 0)...};
// C++17 (fold expression):
(void(do_something(pack)), ...);

当一个重载的 operator 可能会破坏语言的排序保证时。


3
哇,我从未听说过有人超载了,运算符。 - iBug
5
@iBug - 这是C++,我们可以对一切东西进行重载。一切! - StoryTeller - Unslander Monica
3
还不太行:成员选择运算符和三元条件运算符是重要的例外。(尽管 Stroustrup 想放宽前者吗?) - Bathsheba
2
@Simple Naw,你只需要这样做:void(a()), void(b()) - Barry
2
@Simple 如果你必须防范过载的 operator,那么在我看来,你和错误的人合作了。 - cmaster - reinstate monica
显示剩余12条评论

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