#c #visual-c #scope #overloading #scope-resolution
#c #visual-c #область видимости #перегрузка #разрешение области видимости
Вопрос:
В чем причина, по которой функция bar()
не может быть перегружена здесь?
namespace foo
{
void bar(int) { }
struct baz
{
static void bar()
{
// error C2660: 'foo::baz::bar' : function does not take 1 arguments
bar(5);
}
};
}
Ответ №1:
Его нельзя перегрузить, потому что они находятся в разных областях. Первый bar
находится в foo::bar
, а второй — в foo::baz::bar
.
Имя bar
из внешнего пространства имен скрыто объявлением new . Это должно быть либо вызвано явно, либо сделано видимым с помощью объявления using:
static void bar()
{
using foo::bar;
bar(5);
}
Комментарии:
1. Верно, но разве сбой не может сообщить компилятору, что он должен продолжить поиск? Почему он терпит неудачу, не попробовав что-то еще?
2. Компилятор не работает с помощью hit и trial. Это работает так, как вы просите, чтобы это работало. Он может оптимизировать, но не может принимать разумные решения от вашего имени. Более того, поскольку область действия ваших функций различна, компилятор не может определить, какую реализацию вы хотите использовать. Учтите, что у вас есть более двух функций bar, определенных в более чем двух областях. Тогда было бы лучше, чтобы компилятор выдал ошибку, а не проявил разум и выбрал реализацию, которая может вам подойти, а может и не подойти.
3. Ах, я только что понял, что, если бы компилятор сделал это, это позволило бы перехватить функцию-член из-за неявных преобразований, которые могут оказаться хуже совпадающими локально, чем глобально. Я думаю, было бы неплохо упомянуть и об этом.
4. @krammer:
Compiler doesn't work by hit and trial.
—> SFINAE?
Ответ №2:
Это то, что вы пытаетесь сделать?
namespace foo
{
void bar(int) { }
struct baz
{
static void bar()
{
// error C2660: 'foo::baz::bar' : function does not take 1 arguments
foo::bar(5); // <-- changed
}
};
}
РЕДАКТИРОВАТЬ: это также, очевидно, не будет перегружать.