工厂函数使用variadic args模板和unique_ptr

时间:2017-02-06 21:24:07

标签: c++ templates factory-pattern

在Scott Meyers的Effective Modern C ++第18项中,有一个未完成的工厂函数,如下面的代码所示。我试图完成它,但是,如果派生类有构造函数采用不同的参数,这个代码明显的原因不会编译。这是使用可变参数模板函数编写工厂函数的正确方法,还是应该使用SFINAE或其他一些习惯用法?

http://coliru.stacked-crooked.com/a/48b30d4f97133b9f

#include <string>
#include <memory>

class Base {
 public:
  virtual ~Base() = default;
};

class Derived1 : public Base {
 public:
  Derived1(std::string s, int i) {}
};

class Derived2 : public Base {
 public:
  Derived2(std::string s, std::string s2) {}
};

enum class BaseType {
  Derived1,
  Derived2
};

template<typename... Ts>
std::unique_ptr<Base> makeBase(BaseType type, Ts&&... args) {
  std::unique_ptr<Base> ptr;
  if (type == BaseType::Derived1)
    ptr.reset(new Derived1(std::forward<Ts>(args)...));
  if (type == BaseType::Derived2)
    ptr.reset(new Derived2(std::forward<Ts>(args)...));
  return ptr;
}

int main() {
  auto d1 = makeBase(BaseType::Derived1, "aa", 1);
}

错误:

main.cpp: In instantiation of 'std::unique_ptr<Base> makeBase(BaseType, Ts&& ...) [with Ts = {const char (&)[3], int}]':
main.cpp:35:53:   required from here
main.cpp:30:19: error: no matching function for call to 'Derived2::Derived2(const char [3], int)'
         ptr.reset(new Derived2(std::forward<Ts>(args)...));
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:16:7: note: candidate: Derived2::Derived2(std::__cxx11::string, std::__cxx11::string)
       Derived2(std::string s, std::string s2) {}
       ^~~~~~~~
main.cpp:16:7: note:   no known conversion for argument 2 from 'int' to 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}'
main.cpp:14:11: note: candidate: constexpr Derived2::Derived2(const Derived2&)
     class Derived2 : public Base {
           ^~~~~~~~
main.cpp:14:11: note:   candidate expects 1 argument, 2 provided
main.cpp:14:11: note: candidate: constexpr Derived2::Derived2(Derived2&&)
main.cpp:14:11: note:   candidate expects 1 argument, 2 provided

0 个答案:

没有答案