2017-08-28 64 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); 
// ^^^^^^^^ 
相关问题