声明和定义同时进行为什么不被允许?

5

我不明白,为什么不能写:

struct foo {      
    void bar();                                     // declaration
    void bar(){std::cout << "moo" << std::endl;}    // declaration + definition
};

该函数被声明了两次(我以为这样是可以的),但只被定义了一次。然而,我的编译器报错:
decldef.cxx:7:10: error: 'void foo::bar()' cannot be overloaded

为什么不允许这样做?

为什么我的编译器(g++ 4.7.2)会把这个解释为重载?

PS:我知道该如何“正确地”编写它,但我只是想知道为什么上述方法是错误的。


确实,但我认为这个问题比那更深入。举个例子,如果将struct替换为namespace,那么这段代码就是合法的。 - Bathsheba
好问题,确实是的。 "+定义" 部分实际上是无关紧要的;即使具有相同签名的重复声明在此也是不允许的。 - mindriot
2个回答

10

来自§9.3

除了出现在类定义之外的成员函数定义,以及类模板和成员函数模板(14.7)的显式特化,出现在类定义之外,成员函数不得重新声明

此外,在这种情况下,这些语句也可能违反:

成员函数可以在其类定义中定义(8.4),这种情况下它是一个内联成员函数(7.1.2),或者如果它已经在其类定义中被声明但未被定义,则可以在类定义之外定义。

由于第一次声明并未声明该函数为inline。第二个定义隐含地将其声明为inline

然而,仔细考虑后,这个声明似乎不太可信。


3
如果这是正确的答案,为什么 struct foo { void bar(); void bar(); }; 会出现完全相同的错误信息呢?(原文已经是中文了) - DevSolar
4
你所引用的第二部分是真正回答问题的部分:“_成员函数不应重新声明_”。在这种情况下,内联的区别并不真正重要。 - mindriot
1
@RichardHodges:你去掉关于inline的误导性部分,我就撤回我的踩和回答,因为你已经提供了正确的标准引用。;-) - DevSolar
所以这是成员函数的特殊规则,对吧? - 463035818_is_not_a_number
@tobi303 看起来是这样的,是的。 - Richard Hodges

5

该函数被声明两次(我以为这样没问题),但只定义了一次。

无论你第二次定义函数与否,这都是独立的。重点在于你 声明 了函数两次,这是不允许的

同样会出现编译错误信息,这也是不能通过编译的:

struct foo {
    void bar();
    void bar();
};

在类定义内部,您不能使用相同的参数列表重新声明相同的函数:

'void foo::bar()' cannot be overloaded with 'void foo::bar()'.

确实。那么标准中是否有明确的声明说明为什么不允许这样做?在我看来,编译器的错误信息最多是误导性的,因为这并不是真正的重载... - mindriot
@mindriot:Richard Hodges已经(编辑进去了)这段引用。我手头没有C++标准的副本。 - DevSolar

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