2017-08-28 32 views
2

使用C++ 14,我試圖擴展this實現以支持ObserverCallback方法,該方法將在外部調用。將可變參數模板包裝爲元組向量

MyClass容器使用元組向量,其類型由可變參數模板指定。訪問矢量然後可以使用訪問< T>()完成。

我需要的是實現一個觀察者,它應該向矢量添加元素。因爲元素的類型可以是任何類型的元組,我已經模板一樣好:

template <typename ...T> 
class Wrapper{ 
public: 
    MyClass<T...> mc; 

    template <typename U> 
    void ObserverCallback(const U& element){ 
     mc.access<U>().push_back(element); 
    } 
}; 

似乎有被包裝類的錯誤:

variadic2.cpp: In member function 'void Wrapper<T>::ObserverCallback(const U&)': 
variadic2.cpp:71:20: error: expected primary-expression before '>' token 
     mc.access<U>().push_back(element); 
        ^
variadic2.cpp:71:22: error: expected primary-expression before ')' token 
     mc.access<U>().push_back(element); 
        ^
variadic2.cpp: In function 'int main(int, char**)': 
variadic2.cpp:87:10: error: 'class MyClass<float, std::reference_wrapper<int>, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' has no member named 'ObserverCallback' 
    w.mc.ObserverCallback(string("a")); 

對於參考,我還附上了完整的源代碼清單:

#include <tuple> 
#include <vector> 
#include <functional> 
#include <iostream> 
#include <string> 

using namespace std; 

template <class T1, class T2> 
struct SameType 
{ 
    static const bool value = false; 
}; 

template<class T> 
struct SameType<T, T> 
{ 
    static const bool value = true; 
}; 

template <typename... Types> 
class MyClass 
{ 
    public: 
    typedef tuple<vector<Types>...> vtype; 
    vtype vectors; 

    template<int N, typename T> 
    struct VectorOfType: SameType<T, 
     typename tuple_element<N, vtype>::type::value_type> 
    { }; 

    template <int N, class T, class Tuple, 
       bool Match = false> // this =false is only for clarity 
    struct MatchingField 
    { 
     static vector<T>& get(Tuple& tp) 
     { 
      // The "non-matching" version 
      return MatchingField<N+1, T, Tuple, 
        VectorOfType<N+1, T>::value>::get(tp); 
     } 
    }; 

    template <int N, class T, class Tuple> 
    struct MatchingField<N, T, Tuple, true> 
    { 
     static vector<T>& get(Tuple& tp) 
     { 
      return std::get<N>(tp); 
     } 
    }; 

    template <typename T> 
    vector<T>& access() 
    { 
     return MatchingField<0, T, vtype, 
       VectorOfType<0, T>::value>::get(vectors); 
    } 
}; 

template <typename ...T> 
class Wrapper{ 
public: 
    MyClass<T...> mc; 

    template <typename U> 
    void ObserverCallback(const U& element){ 
     mc.access<U>().push_back(element); 
    } 
}; 

int main(int argc, char** argv) 
{ 
    int twelf = 12.5; 
    typedef reference_wrapper<int> rint; 

    Wrapper<float, rint, string> w; 
    vector<rint>& i = w.mc.access<rint>(); 

    i.push_back(twelf); 

    w.mc.access<float>().push_back(10.5); 

    w.ObserverCallback(string("a")); 

    cout << "Test:\n"; 
    cout << "floats: " << w.mc.access<float>()[0] << endl; 
    cout << "ints: " << w.mc.access<rint>()[0] << endl; 
    cout << "strings: " << w.mc.access<string>()[0] << endl; 
    //w.access<double>(); 

    return 0; 
} 

回答

5

mc的類型取決於T...,所以你必須指定其access部件S應該是函數模板:

mc.template access<U>().push_back(element); 
// ^^^^^^^^