다음 코드가 컴파일되어 실행된다는 것에 어떻게 든 놀랐습니다 (vc2012 & gcc4.7.2)
class Foo {
struct Bar { int i; };
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout << b.i;
}
이 코드가 제대로 컴파일되는 것이 맞습니까? 왜 정확합니까? auto
개인 유형으로 사용할 수 있는데 예상대로 이름을 사용할 수없는 이유는 무엇 입니까?
답변
auto
대부분 의 경우 규칙 은 템플릿 유형 공제와 동일합니다. 게시 된 예제는 개인 유형의 객체를 템플릿 함수에 전달할 수있는 것과 같은 이유로 작동합니다.
template <typename T>
void fun(T t) {}
int main() {
Foo f;
fun(f.Baz()); // ok
}
그리고 왜 개인 유형의 객체를 템플릿 함수에 전달할 수 있습니까? 유형의 이름 만 액세스 할 수 없기 때문입니다. 유형 자체는 여전히 사용할 수 있으므로 클라이언트 코드로 반환 할 수 있습니다.
답변
액세스 제어는 이름에 적용됩니다 . 표준의이 예와 비교하십시오.
class A {
class B { };
public:
typedef B BB;
};
void f() {
A::BB x; // OK, typedef name A::BB is public
A::B y; // access error, A::B is private
}
답변
이 질문은 이미 chill과 R. Martinho Fernandes에 의해 매우 잘 대답되었습니다.
해리포터 비유로 질문에 대답 할 수있는 기회를 막을 수 없었습니다.
class Wizard
{
private:
class LordVoldemort
{
void avada_kedavra()
{
// scary stuff
}
};
public:
using HeWhoMustNotBeNamed = LordVoldemort;
friend class Harry;
};
class Harry : Wizard
{
public:
Wizard::LordVoldemort;
};
int main()
{
Wizard::HeWhoMustNotBeNamed tom; // OK
// Wizard::LordVoldemort not_allowed; // Not OK
Harry::LordVoldemort im_not_scared; // OK
return 0;
}
해리 허점을 상기시켜 준 Quentin에게 감사드립니다.
답변
여기에 문제가 정말 함께 할 수없는 것을 보여 98 ++ C에서 예입니다, 다른 (좋은) 답변을 추가하려면 auto
모두에서
class Foo {
struct Bar { int i; };
public:
Bar Baz() { return Bar(); }
void Qaz(Bar) {}
};
int main() {
Foo f;
f.Qaz(f.Baz()); // Ok
// Foo::Bar x = f.Baz();
// f.Qaz(x);
// Error: error: ‘struct Foo::Bar’ is private
}
개인 유형을 사용하는 것은 금지되지 않으며 유형의 이름 만 지정했습니다. 예를 들어, 모든 버전의 C ++에서 이름이없는 임시 유형을 작성해도됩니다.