2017-05-12 181 views
2

On C++ weekly ep. 48 by Jason Turner有下面的代碼:可變參數類模板和可變參數的構造函數

template<typename ... B> 
struct Merged : B... 
{ 
    template <typename ... T> 
    Merged(T && ... t) : B(std::forward<T>(t))... 
    { } 

    using B::operator()...; 
}; 

它無法與GCC 7.1以下幾點:

error: mismatched argument pack lengths while expanding 'B' 

什麼是擴大B中的正確方法是什麼?

(順便說一句,在上面的鏈接,代碼似乎編譯了一些7.0快照)。

EDIT1:

正如@ Jarod42指出,這將對於結構充當仿函數編譯。實際的視頻使用lambda,它似乎打破了那裏。

auto l1 = [] { return 4 ; }; 
auto l2 = [](const int i) { return i * 10; }; 
// This would work, S1, S2 are just functors structs 
Merged<S1, S2> merged1(42, "hello"); 
// This fails 
Merged merged2 = Merged(l1, l2); 

EDIT2:

好像用戶定義的扣除導遊不在這裏工作了。

template <typename ... T> 
Merged(T...) -> Merged<std::decay_t<T>...>; 

上面應該有啓用以下:

Merged merged(l1, l2); 

但事實並非如此。好像你必須通過類型合併<>

Merged<t1, t2> merged(l1, l2); 

這可能算不上什麼教程想證明。

+0

是不是C++ 17而不是C++ 11?至少我得到[與c + + 11編譯時完全不同的錯誤](http://ideone.com/Pd4tRO) – user463035818

+2

我想你已經提供了錯誤數量的參數給構造函數? – Quentin

+0

Works [here](http://coliru.stacked-crooked.com/a/5bdcaecb54f760c2)。 – Jarod42

回答

1

隨着

template <typename ... T> 
Merged(T&& ... t) : B(std::forward<T>(t))... 
{} 

sizeof...(T)應該等於sizeof...(B): 你必須提供由基地之一的說法。然後它works

如果你不提供相同數量的說法,你HACE類似的錯誤:

error: mismatched argument pack lengths while expanding 'B'

+0

OK @ Jarod42。似乎問題來自lambda部分。 [this](https://godbolt.org/g/VFRzV8)不起作用。該鏈接將非常接近視頻中的實際代碼。 – Kobi

+1

看來這是自動類型扣除失敗,請參閱[使用lambda修改示例](https://godbolt.org/g/Nfs4Ph) – Jarod42

+0

Bingo @ Jarod42。這樣可行。謝謝! – Kobi

2

好像有沒有必要在這裏定義的任何構造,而是,只是使用C++ 17骨料:

template<typename ... B> 
struct Merged : B... 
{ 
// This is not needed, it would actually render this class 
// to be a non-aggregate one. 
// template <typename ... T> 
// Merged(T && ... t) : B(std::forward<T>(t))... 
// { } 

    using B::operator()...; 
}; 

// C++17 class deduction guidance (user defined) 
template <typename ... T> 
Merged(T...) -> Merged<T...>; 

int main() 
{ 
    auto l1 = [] { return 4 ; }; 
    auto l2 = [](const int i) { return i * 10; }; 
    // Note here, using {} for initializing an aggregate 
    Merged merged{l1, l2}; 
} 

注C++ 17類扣除用戶定義的指導,使用加{}用於初始化的集合體。

構造函數是不需要的。如果我們擁有它,這個類將不再是聚合,並且用於初始化的語法將停止工作。