让我们说,我在" foo.hpp"中有以下内容。我有函数,其名称与 struct 相同。
int foo(int i);
struct foo{
foo(int i){ value = i;}
operator int() {return value;}
int value;
};
如果我这样称呼它是主要的:
int main()
{
std::cout << foo(1) << std::endl; // function is called, not the struct, why??
}
为什么编译器总是链接函数而不是结构?如果可能,如何更改结构链接,而不是函数?
最终,我想通过添加额外的头文件并用struct覆盖函数来覆盖库中的函数。这样,我希望改变一个特定的功能,但继续使用所有其他库函数,而不是同时改变库代码。
答案 0 :(得分:11)
根据C ++标准N4431 §3.3.10/ 2名称隐藏[basic.scope.hiding] (强调我的):
类名 (9.1)或枚举名称(7.2)可以通过变量的名称隐藏,数据会员, 在同一范围内声明的函数,或枚举器。如果是类或枚举名称和变量,数据 成员,函数或枚举器在相同的范围内(以任何顺序)声明,具有相同的名称, 变量,数据成员,函数或枚举数名称所在的位置隐藏了或枚举名称 可见。强> 的
将struct foo
或函数foo
放入其自己的namespace
。
答案 1 :(得分:1)
这里有很多事情发生。
如果在结构中有一个与结构同名的函数,那么它就是“构造函数”。调用它来填充结构的成员变量。在您的情况下,构造函数foo将“i”的值赋给成员变量“value”。
然后在main中构造一个struct foo对象,给它赋值1.在上下文中,编译器发现你已经为int提供了一个转换操作符,它用它将对象传递给流。< / p>
所以我不确定我理解你认为结构应该链接在哪里而不是函数。您可以调用构造函数来创建对象。你实际上不能调用结构。 (除非你在其中创建一个operator(),然后你可以调用该结构的成员函数。但你没有做出其中一个,所以“调用结构”没有意义。)
至于覆盖库函数 - 您是否可以访问要调用新函数的代码?将调用更改为新函数并不会令人困惑。如果您必须更改但无法更改源,则可以(通常)在同一组对象模块中提供具有完全相同签名的新函数,并且将在链接器在库中找到其他版本之前使用它。但你想要的是一个函数,而不是一个结构。