2012-06-14 2 views
8

다음 코드에서 가변 생성자는 두 번 호출됩니다. 적절할 때 가변 인수 생성자의 단일 인수 버전 대신 호출되는 복사 생성자를 얻으려면 어떻게해야합니까?가변 생성자를 통해 호출되는 복사 생성자를 얻으려면 어떻게해야합니까?

#include <iostream> 

struct Foo 
{ 
    Foo(const Foo &) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template<typename... Args> 
    Foo(Args&&... args) 
    { 
     std::cout << "variadic constructor\n"; 
    } 

    std::string message; 
}; 

int main() 
{ 
    Foo f1; 
    Foo f2(f1); // this calls the variadic constructor, but I want the copy constructor. 
} 

답변

9

이것은 실제로 생성자가 가변적이라는 사실과 아무 관련이 없습니다. Variadic이 아닌 생성자 템플릿을 사용하는 다음 클래스는 동일한 동작을 나타냅니다.

struct Foo 
{ 
    Foo() { } 

    Foo(const Foo& x) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template <typename T> 
    Foo(T&& x) 
    { 
     std::cout << "template constructor\n"; 
    } 

}; 

문제는 생성자 템플릿이 더 적합하다는 것입니다. 복사 생성자를 호출하려면 const가 아닌 lvalue f1const Foo&에 바인딩하려면 자격 변환이 필요합니다 (const qualification을 추가해야합니다). 생성자 템플릿을 호출하려면

는 어떤 변환이 필요하지 않습니다 : T은 붕괴 참조 후하는 Foo&로 추론 할 수있다 ( Foo& && -> Foo&), 매개 변수 x 유형 Foo&을 제공합니다.

비 const 왼쪽 값 참조 매개 변수 Foo&이있는 두 번째 복사본 생성자를 제공하면이 문제를 해결할 수 있습니다.

+1

lvalue ('f1')가'T &&'에 바인드 할 수 없기 때문에, 참조 축소 (즉,?), 즉'T &&&'=>'T &'가 약간 더 있습니다. –

4

다만 종래의 복사 생성자 이외에 일치 검색 과부하 비 constFoo&로, 즉 하나를 제공한다. 그런 다음 명시 적 캐스트를 통해 호출을 위임 할 수 있습니다.

Foo(Foo& other) : Foo(static_cast<Foo const&>(other)) { } 
관련 문제