How can I fix my compilation errors with this template which uses a variadic template variable

时间:2018-09-18 19:34:05

标签: c++11 variadic-templates

I am learning to code with variadic template and wrote a simple variadic template to experiment. The compiler complains about the m_bindingObj member variable with template argument 1 is invalid. What I am missing?

#include <iostream>
#include <functional>

class ClassA
{
public:

   static ClassA * construct(int varA, int varB, int varC)
   {
      return new ClassA(varA, varB, varC);
   }


   ClassA(int varA, int varB, int varC)
      : m_varA(varA)
      , m_varB(varB)
      , m_varC(varC) {}

   static std::function<ClassA *(int, int, int)> getBinding() { return std::bind(&ClassA::construct, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); }

   int m_varA;
   int m_varB;
   int m_varC;
};


template <typename T>
class ToolFactory
{
public:

   template <typename... Args>
   static T * invoke(Args... args)
   {
      std::function<T*(Args...)> creator = getCreator<Args...>();
      return creator(args...);
   }

   template <typename... Args> static std::function<T*(Args...)> getCreator() {
      return T::getBinding();
   }
   template <typename... Args> static std::function<T*(Args...)> m_bindingObj;
};

template <typename T> std::function<T*(Args...)> ToolFactory<T>::m_bindingObj;

int main()
{
   ToolFactory<ClassA>::invoke(1, 2, 3);

    return 0;
}

With the fixed typo provided by bobah I have reworked the example which shows an example of the used of m_bindingObj.

#include <iostream>
#include <functional>

class ClassA
{
public:

   static ClassA * construct(int varA, int varB, int varC)
   {
      return new ClassA(varA, varB, varC);
   }


   ClassA(int varA, int varB, int varC)
      : m_varA(varA)
      , m_varB(varB)
      , m_varC(varC) {}

   static std::function<ClassA *(int, int, int)> getBinding() { return std::bind(&ClassA::construct, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); }

   int m_varA;
   int m_varB;
   int m_varC;
};

class ClassB 
{
public:

   static ClassA * construct(int varA, int varB, int varC)
   {
      return new ClassA(varA, varB, varC);
   }
   static std::function<ClassA *(int, int, int)> getBinding() { return std::bind(&ClassB::construct, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); }
};

template <class T>
class ToolFactory
{
public:

   template <typename... Args>
   static T * create(Args... args)
   {
      return m_bindingObj<Args...>(args...);
   }
   template<typename... Args> static void setBinding(std::function<T*(Args...)> functor) {
      m_bindingObj<Args...> = functor;
   }
   template <typename... Args> static std::function<T*(Args...)> m_bindingObj;
};

template<class T> template<typename... Args> std::function<T*(Args...)> ToolFactory<T>::m_bindingObj = T::getBinding();

int main()
{
    ToolFactory<ClassA>::setBinding(ClassB::getBinding());
    ClassA * instance = ToolFactory<ClassA>::create(1, 2, 3);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

Few typos plus you need C++14 if you need the variable template syntax support. Would be great to see an example of what a m_bindingObj member variable is used for, as whether my variant is correct or not depends on that.

template <typename T>
class ToolFactory
{
   ...
   template <typename... Args> static std::function<T*(Args...)> m_bindingObj;
};

template <typename T>
template <typename... Args>
std::function<T*(Args...)> ToolFactory<T>::m_bindingObj;