Ошибка компилятора C3767
Обновлен: Ноябрь 2007
Сообщение об ошибке
нет доступа к функции-кандидату (функциям-кандидатам) "функция".
'function' candidate function(s) not accessible.
Дружественная функция, определенная в классе, не будет обрабатываться так же, как при ее определении и объявлении в области глобального пространства имен. Тем не менее она может быть найдена при поиске с зависимостью от аргументов.
Ошибка C3767 может также возникнуть в результате критических изменений: собственные типы в компиляции /clr стали частными по умолчанию; дополнительные сведения см. в разделе Type Visibility.
Следующий пример демонстрирует причины возникновения ошибки C3767:
// C3767a.cpp
// compile with: /clr
using namespace System;
public delegate void TestDel();
public ref class MyClass {
public:
static event TestDel^ MyClass_Event;
};
public ref class MyClass2 : public MyClass {
public:
void Test() {
MyClass^ patient = gcnew MyClass;
patient->MyClass_Event();
}
};
int main() {
MyClass^ x = gcnew MyClass;
x->MyClass_Event(); // C3767
// OK
MyClass2^ y = gcnew MyClass2();
y->Test();
};
Следующий пример демонстрирует причины возникновения ошибки C3767:
// C3767b.cpp
// compile with: /clr:oldSyntax
using namespace System;
__delegate void TestDel();
public __gc class MyClass {
public:
static __event TestDel * MyClass_Event;
};
public __gc class MyClass2 : public MyClass {
public:
void Test() {
MyClass* patient = new MyClass;
patient->MyClass_Event();
}
};
int main() {
MyClass* x = new MyClass;
x->MyClass_Event(); // C3767
// OK
MyClass2 * y = new MyClass2();
y->Test();
};
Следующий пример демонстрирует причины возникновения ошибки C3767:
// C3767c.cpp
// compile with: /clr /c
ref class Base {
protected:
void Method() {
System::Console::WriteLine("protected");
}
};
ref class Der : public Base {
void Method() {
((Base^)this)->Method(); // C3767
// try the following line instead
// Base::Method();
}
};
Следующий пример демонстрирует причины возникновения ошибки C3767:
// C3767d.cpp
// compile with: /clr:oldSyntax /c
__gc class Base {
protected:
void Method() {
System::Console::WriteLine("protected");
}
};
__gc class Der : public Base {
void Method() {
((Base*)this)->Method(); // C3767
// try the following line instead
// Base::Method();
}
};
В Visual C++ .NET 2002 метод поиска символов в компиляторе был изменен. Ранее в некоторых случаях компилятор выполнял автоматический поиск символов в заданном пространстве имен. Теперь компилятор использует поиск с зависимостью от аргументов. Дополнительные сведения см. в разделе Сводная информация о критических изменениях, которые могут приводить к ошибкам компиляции.
Следующий пример демонстрирует причины возникновения ошибки C3767:
// C3767e.cpp
namespace N {
class C {
friend void FriendFunc() {}
friend void AnotherFriendFunc(C* c) {}
};
}
int main() {
using namespace N;
FriendFunc(); // C3767 error
C* pC = new C();
AnotherFriendFunc(pC); // found via argument-dependent lookup
}
Для кода, допустимого в Visual C++ .NET 2003 и Visual C++ .NET 2002, следует объявить в области класса дружественную функцию и определить ее в области пространства имен:
// C3767f.cpp
class MyClass {
int m_private;
friend void func();
};
void func() {
MyClass s;
s.m_private = 0;
}
int main() {
func();
}