繁体   English   中英

使用默认参数的 C++ 函数的多个声明

[英]Multiple declarations of C++ functions with default parameters

我对几乎所有东西都使用 typedef,包括函数。 在过去的几周里,我一直在改进我们的 C++ 代码,以尽可能完全符合 ISO C++11 标准,并使用最终草案文档 (N3242) 作为指南。

正如我们所知,偶尔会有多个声明通过出现在多个文件中的 extern 或重复的 typedef 潜入我们的代码中。 根据上述doco第145页第7.1.3节的摘录,这应该是无害的:

3. 在给定的非类 scope 中,typedef 说明符可用于重新定义在 scope 中声明的任何类型的名称,以引用它已经引用的类型。

[ 例子:

 typedef struct s { /*... */ } s; typedef int I; typedef int I; typedef II;

—结束示例]

所以,我写了一个程序来测试这个。 最简单的形式:

typedef int (fcntype)(int, int);
extern fcntype fcn1;

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2, 3); }

使用 gcc 编译

 -Wfatal-errors -Wswitch-default -Wswitch-enum -Wunused-parameter -Wfloat-equal -Wundef -c -Wstrict-null-sentinel -std=c++0x -pedantic -Wall -Wextra

当然,没有问题。 让我们复制 function 声明:

typedef int (fcntype)(int, int);
extern fcntype fcn1;
extern fcntype fcn1; // woops. probably from an #include ...

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2, 3); }

正如标准预测的那样,没有问题。 让我们对原始版本进行不同的更改:

typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2); } // use the default param

再次,没有问题。 当我们同时拥有重复的 decl 和默认参数时,问题就出现了,如下所示:

typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
extern fcntype fcn1; // FYI this is line 3 in the error message below.

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2); } // use the default param

gcc 抱怨

decltest.cpp:3: error: default argument given for parameter 2 of ‘int fcn1(int, int)’

当然,我正在按照应该清理的方式清理代码,也就是说,我将 decls 归为一个组织更好的文件。 但这是编译器中的错误还是我对默认参数“是”的误解?

首先,对于相同类型的相同 function 声明,最多只能有一个声明定义默认的 arguments。 这是由于 §8.3.6 [dcl.fct.default]/4:

...默认参数不应由以后的声明重新定义(甚至不能重新定义为相同的值)。 [示例

 ... void m() { void f(int, int); // has no defaults f(4); // error: wrong number of arguments void f(int, int = 5); // OK f(4); // OK, calls f(4, 5); void f(int, int = 5); // error: cannot redefine, even to same value }...

结束示例] ...

此外,正如@Sven 注意到的那样,默认参数不应出现在typedef中,尽管 g++ 即使使用-pedantic也无法捕捉到它。 我认为clangVisual C++拒绝这个,但我没有尝试过。

您的标准报价在这里不适用,因为您没有多次声明 typedef,而是多次使用它。

默认 arguments 确实是一个棘手的情况,它们只能出现在一个声明中(请记住,定义本身也算作声明,即使将默认参数同时放在前向声明和定义中也是错误的)。

这会产生相同的错误:

extern int fcn1(int, int=0);
extern int fcn1(int, int=0);

因此,您的typedef版本不起作用也就不足为奇了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM