2015-09-29 15 views
9

Mam zmiennej liczbie argumentów klasy szablonC++ o zmiennej liczbie argumentów szablonu iterate wektorowe i porównywanie elementów

template <size_t ...T> 
struct Foo 
{ 
    std::vector<size_t> t; 

    bool IsEqual() 
    { 
    //?? 
    } 

}; 

który chcę użyć jak:

Foo<1,2,3,4> foo; 
foo.data = {1,2,3,4}; 
foo.IsEqual(); 

Jak mogę wdrożyć IsEqual iteracyjne i porównać każdy element wektor i return false/true, jeśli elementy są w tej samej kolejności, co parametry szablonu?

Odpowiedz

6

Użyj sekwencji Indeks trick:

bool IsEqual() 
{ 
    return t.size() == sizeof...(T) && 
     IsEqual(std::make_index_sequence<sizeof...(T)>{}); 
} 

z:

template <size_t... Is> 
bool IsEqual(std::index_sequence<Is...>) { 
    bool valid = true; 
    using expander = int[]; 
    expander{0, 
     (valid = valid && t[Is] == T, 
     0)... 
    }; 

    return valid; 
}  

Może nawet to zrobić w jednej funkcji, korzystając z faktu, że każdy obliczeń wartość a skutkiem ubocznym w Klauzula inicjalizatora jest sekwencjonowana przed następną, wykonując to za jednym razem:

bool IsEqual() 
{ 
    if (t.size() == sizeof...(T)) { 
     auto it = t.begin(); 
     bool valid = true; 

     using expander = int[]; 
     expander{0, 
      (valid = valid && *it++ == T, 
      0)... 
     }; 

     return valid; 
    } 
    else { 
     return false; 
    } 
} 
+0

Czy możesz wyjaśnić nieco, jak to działa? – syntagma

2

Po prostu rozpakuj argumenty szablonu.

template <size_t ...T> 
struct Foo 
{ 
    std::vector<size_t> t; 

    bool IsEqualTemplate(size_t index) 
    { 
    return true; 
    } 

    template <typename FIRSTARG, typename ...OTHERARGS> 
    bool IsEqualTemplate(size_t index, FIRSTARG firstArg, OTHERARGS... otherArgs) 
    { 
    return t[index] == firstArg && IsEqualTemplate(index + 1, otherArgs...); 
    } 

    bool IsEqual() 
    { 
    return t.size() == sizeof...(T) ? IsEqualTemplate(0, T...) : false; 
    } 
}; 
+0

Teraz wygląda dobrze. Może trochę uprościć. Po prostu nie musisz już sprawdzać, czy 'index Barry

+0

Po prostu lubię operatora trójskładnikowego. :) –

Powiązane problemy