2012-03-22 47 views
3

我正在寫一個升降機,應該將一個變量arity函數提升到某個std :: vectors中,該vector類似於一個帶索引的SQL表。我想將f參數應用於所有向量中具有相同id的每組元素。我遇到了一個模板推理的問題,我在這裏將它提煉出來(減去迭代器邏輯)。我寫了我認爲是明智的遞歸案例,但模板演繹認爲它不可行。構建新的模板參數時可以使用一個可變參數模板參數嗎?

// Simple container type 
template <typename T> 
struct A { 
    T x; 
    T y; 
    T z; 
}; 

// Wrapper type to differentiate an extracted value from a container 
// in template deduction 
template <typename T> 
struct B { 
    T value; 
}; 

// Base case. All A<Ts> have been extracted to B<Ts>. 
template <typename F, typename... Ts> 
void lift (F f, B<Ts> ...bs) { 
    // Call f with extracted values 
    f(bs.value...); 
} 

// Recursive case 
template <typename F, typename T, typename... Ts, typename Us> 
void lift (F f, A<T> a, A<Ts> ...as, B<Us> ...bs) { 
    // Copy a value from the beheaded container A<T>. 
    B<T> b = {a.x}; 
    // Append this B<T> to args and continue beheading A<Ts>. 
    lift(f, as..., bs..., b); 
} 

// Test function 
template <typename... Ts> 
struct Test { 
    void operator() (Ts...) {} 
}; 

int main() { 

    B<int> b = {1}; 
    // No errors for the base case 
    lift(Test<>()); 
    lift(Test<int, int>(), b, b); 

    // error: no matching function for call to 'lift' 
    // The notes refer to the recursive case 
    A<int> a = {1,0,0}; 
    lift(Test<int>(), a); // note: requires at least 3 arguments, but 2 were provided 
    lift(Test<int>(), a, a); // note: requires 2 arguments, but 3 were provided 
    lift(Test<int>(), a, a, b); // note: requires 2 arguments, but 4 were provided 
} 

這段代碼有什麼問題?

忽略所有東西都在這裏傳遞,以便於閱讀和書寫。爲什麼不這樣編譯?

+0

as'包是不可扣除的,因爲它不在最後一個參數位置。 – 2012-03-23 15:22:49

回答

1

爲什麼不直接提取A和B的值?

template <typename T> 
T extractValue(A<T> a) 
{ 
    return a.x; 
} 
template <typename T> 
T extractValue(B<T> b) 
{ 
    return b.value; 
} 

template <typename F, typename... T> 
void lift (F f, T... values) { 
    f(extractValue(values)...); 
} 

另外,由於參數數量錯誤,您最後的2個測試用例無法編譯。

lift(Test<int,int>(), a, a); 
lift(Test<int,int,int>(), a, a, b); 
+0

爲什麼參數的數量是錯誤的?當可變參數模板函數的目的是什麼時,我如何向可變參數模板函數提供錯誤數量的參數?我不明白。 – 2012-03-22 21:08:07

+0

我不能提取這些值,這只是因爲我在每個容器中都有一個迭代器,並且可能會多次前進,而其他人可能只會在f次調用之間前進一次。我需要爲每個迭代器分別處理這個邏輯,所以我確信我需要在參數中構建摺疊和列表。 – 2012-03-22 21:20:48

+0

@SamuelDanielson:'測試()'只能接受1個參數。你給出了超過1個。 – kennytm 2012-03-23 07:46:53