2016-03-26 61 views
3

更新:
謝謝你,Jamboree。
這是最後的struct AC++ - 推導參數包(variadic模板)的構造函數和複製構造函數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'; 
    } 
}; 

產地:
關於此代碼,

#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)}; 
} 

的輸出是在VC 14.0 vvvvm
但爲什麼輸出不是vvccm
(我想c and d使用拷貝構造函數。我知道,有效的現代C++項目27只使用一個轉發參考。)

+1

這應該是形成不良的使用'Args'非膨脹。 –

+0

但是,如果我使用'std :: remove_reference_t ',它會發生編譯錯誤。 – Caesar

回答

2

因爲bc,是A&編譯器(不是常量限定)當您通過他們到cdArgs &&...args的計數器因此是比const A &更好的匹配。

達到你想要什麼,你可以這樣來做:

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'; 
    } 
};