Переопределение функции C++ с помощью структуры


Скажем, у меня есть следующее в "foo.ТЭЦ". У меня есть функция с тем же именем, что и структура .

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??
}

Почему компилятор всегда связывает функцию, а не структуру? Если возможно, как изменить то, что структура связана, а не функция?

В конечном счете, я хотел бы перезаписать функцию в библиотеке, добавив дополнительный файл заголовка и перезаписав функцию с помощью структуры. Таким образом, я есть надеясь изменить одну конкретную функцию, но продолжая использовать все другие библиотечные функции и не изменяя при этом код библиотеки.

2   3   2015-06-14 02:42:28

2 ответа:

Оправдание

Согласно стандарту C++ N4431 § 3.3.10/2 скрытие имени [basic.масштаб.прятаться] (акцент мой):

имя класса (9.1) или имя перечисления (7.2) может быть скрыто именем переменной , элемента данных, функция, или перечислитель , объявленные в той же области видимости. Если класс или имя перечисления и переменная, данные член, функция или перечислитель объявляются в том же самом область действия (в любом порядке) с тем же именем, класс или имя перечисления скрыто везде, где есть переменная, элемент данных, функция , или имя перечислителя . видимый.

Решение

Поместите либо struct foo, либо функцию foo в свою собственную namespace.

Здесь много чего происходит.

Если у вас есть функция внутри структуры, которая имеет то же имя, что и структура, то это "конструктор". Он вызывается для заполнения переменных-членов структуры. В вашем случае конструктор foo присваивает значение" i "переменной-члену"value".

Затем в main вы строите объект struct foo, присваивая ему значение 1. В этом контексте компилятор обнаруживает, что вы предоставили оператор преобразования в int, который он использует для переходите к объекту, к потоку.

Поэтому я не уверен, что понимаю, где, по вашему мнению, должна быть связана структура, а не функция. Вы можете вызывать конструкторы для создания объектов. На самом деле вы не можете вызвать структуру. (если вы не сделаете оператор() в нем, то вы можете вызвать эту функцию-член структуры. Но вы не сделали ни одного из них, так что нет смысла "вызывать структуру".)

Что касается переопределения библиотечных функций - есть ли у вас доступ к коду, который вы хотите вызвать вашу новую функцию? Это не будет сбивать с толку, чтобы просто изменить вызов, чтобы быть к вашей новой функции. Если вы должны изменить, но не можете изменить Источник, вы можете (часто) предоставить новую функцию с точно такой же сигнатурой в том же наборе объектных модулей, и она будет использоваться до того, как компоновщик найдет другую версию в библиотеке. Но то, что вам нужно, - это функция, а не структура.