2010-06-25 10 views
17

C++ 0x의 부모 생성자를 모두 전달하는 올바른 방법은 무엇입니까?C++의 모든 생성자 전달 0x

나는이 일을되었습니다

class X: public Super { 
    template<typename... Args> 
     X(Args&&... args): Super(args...) {} 
}; 
+0

템플릿 단축키를 사용하는 대신 모든 생성자를 입력하는 것에 대한 어떤 이유가 있습니까? –

+10

예, 시간, 그리고 슈퍼 클래스가 업데이트되면, 그는 유지 보수를 망칠 것입니다. 자동화 된 솔루션은 무한히 우수합니다. – Puppy

+1

@DeadMG - 정말. 그래서베이스가 새로운 생성자를 얻으면 어떻게 될까요? 새 정보가 필요하지 않으면 파생 된 항목을 사용할 필요가 없습니다. 이 시점에서이 자동화 된 "솔루션"은이를 자동으로 처리하여 파생 된 모든 고객에게 제공합니다. 종종 이것은 잘못된 행동입니다. Derived는 업데이트가 필요하지 않은 객체가 없으면 명시 적으로 수행해야합니다. 따라서 생성자를 살펴봄으로써 객체를 빌드하는 방법이 명확해야합니다. variadic 조건을위한 가변성 템플릿을 예약하십시오. –

답변

39

class X: public Super { 
    using Super::Super; 
}; 

를위한 C++ 0X에 더 나은 방법이있다. 당신의 기본 클래스는 int에서 컨버터블이며, 클래스

class Base { 
public: 
    Base(int n); 
}; 

class Specific: public Base { 
public: 
    template<typename... Args> 
    Specific(Args&&... args); 
}; 

void printOut(Specific const& b); 
void printOut(std::string const& s); 

당신은 이

printOut("hello"); 

가 무엇을 호출됩니다

로 전화를 인쇄하는 두 가지 기능이 존재하는 상상? Specific은 문자 배열을 포함하여 모든 인수를 변환 할 수 있기 때문에 모호합니다. 기존 기본 클래스 생성자에 관계없이 을 수행합니다.. 선언을 사용하여 생성자를 상속하는 것은이 작업을 수행하는 데 필요한 생성자 만 선언합니다.

+0

IMHO - 다른 사람이 질문에 직접 답하는 경우에도 받아 들여야 할 대답입니다. –

+0

요하네스에게 감사드립니다. @ 노아 로버츠 : 예. –

+1

'explicit'키워드로 통화를 명확하게하지 않으면 서 동시에 완벽한 전달 템플릿을 사용할 수 있는지 궁금합니다. 아니 내가 자동으로 유도 된 생성자를 생성하는 것이 좋습니다 ... –

5

난 당신이 제대로 전달 일을하려는 경우 Super(std::forward<Args>(args)...)을 할 필요가 생각 . args에는 이름이 있으므로 rvalue 참조 전에 일반 참조에 바인딩됩니다.

그러나 더 중요한 것은, 당신은이 방법으로 복사 생성자를 전달하지 않을 것입니다. 컴파일러는 템플릿 생성자를 고려하지 않기 때문에 여전히 생성자를 생성합니다. 제공된 예제에서는 괜찮습니다. 컴파일러가 생성 한 생성자는 부모 복사 생성자를 호출하기 때문에 원하는대로 사용할 수 있습니다. 그것이 더 복잡한 경우 적절하지 않다면, 직접 작성해야합니다. 당신은 완벽한 포워딩 템플릿, 당신의 유형은 오버로드 확인에 심하게 작동합니다 선언하면

+1

'Super (std :: forward (args) ...)'가 맞아서 꽤 가까웠다. 앞으로 템플릿에 명백한 템플릿 인수가 필요하다는 것을 기억하십시오. – Puppy

+0

나는 그것을 원래 가지고 있었고, 나는 두 번째를 추측했다.수정 해줘서 고마워. –

+0

이것은 훌륭합니다. 당신은 std :: forward가하는 일에 직관을 가지고 있습니까? (1 차 주문입니까?) 왜 우리는 "args ..."라고 쓸 수 없습니까? 그 결과 복사 생성자가 호출됩니까? –

관련 문제