2016-03-26 27 views
3

Güncelleştirme:
Teşekkür ederiz, Jamboree. Bu, struct A son sürümüdür. C++ - parametre paketini (variadic şablon) kurucuyu ve kopya yapıcısını çıkarmak için enable_if_t

struct A 
{ 
    template<class ... Args,class=std::enable_if_t<(sizeof...(Args)!=1)>> 
    A(Args &&...args) 
    { 
     cout<<'v'; 
    } 
    template<class Arg,class=std::enable_if_t<!std::is_base_of<std::remove_reference_t<Arg>,A>::value>> 
    A(Arg &&arg) 
    { 
     cout<<'v'; 
    } 
    A(const A &) 
    { 
     cout<<'c'; 
    } 
    A(A &&) 
    { 
     cout<<'m'; 
    } 
}; 

Menşei

: Bu kodu hakkında
,

#include<iostream> 
#include<type_traits> 
#include<utility> 
using namespace std; 

struct A 
{ 
    template<class ... Args,class=std::enable_if_t< 
     sizeof...(Args)!=1 
     ||!std::is_same<std::remove_cv_t<std::remove_reference_t<Args>>,A>::value>> 
    A(Args &&...args) 
    { 
     cout<<'v'; 
    } 
    A(const A &) 
    { 
     cout<<'c'; 
    } 
    A(A &&) 
    { 
     cout<<'m'; 
    } 
}; 

int main() 
{ 
    A a{10}; 
    A b{10,20}; 
    A c{b}; 
    const A d{c}; 
    A e{move(c)}; 
} 

çıktı VC++ 14.0 yılında vvvvm olduğunu.
Ancak neden çıktı vvccm değil?
(ı kopya kurucu kullanmak c and d istiyoruz. Ve ++ Madde 27 kullanımı yalnızca bir yönlendirme referansı Etkili Modern C biliyorum.)

+1

Bu kullanma kötü oluşturulmalıdır 'Args' genişletilmemiş. –

+0

Ancak std :: remove_reference_t 'kullanırsam derleme hatası oluşur. – Caesar

cevap

2

b ve c Çünkü derleyici (const nitelikli değil) bunları geçerken için A& olduğunu c ve d, Args &&...args sayılı cetvele göre const A &'dan daha iyi bir eştir.

Eğer bu şekilde yapabileceğini, İstediğinizi elde etmek için:

struct A 
{ 
    A() = default; 

    template<class ... Args,std::enable_if_t<(sizeof...(Args)>1), bool> = true> 
    A(Args &&...args) 
    { 
     cout<<'v'; 
    } 

    template<class Arg,std::enable_if_t<!std::is_base_of<A, std::remove_reference_t<Arg>>::value, bool> = true> 
    A(Arg && arg) 
    { 
     cout<<'v'; 
    } 

    A(const A &) 
    { 
     cout<<'c'; 
    } 
    A(A &&) 
    { 
     cout<<'m'; 
    } 
}; 
İlgili konular