活跃农民
- 积分
- 537
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2019-3-31
- 最后登录
- 1970-1-1
|
本帖最后由 feitao 于 2019-6-15 14:56 编辑
根据下面的网址改编:
- /// [url]https://stackoverflow.com/a/29154449[/url]
- /// [url]https://wandbox.org/permlink/wghDJw5xbDHVZ52x[/url]
- #include <iostream>
- #include <memory>
- #include <stdexcept>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include <gtest/gtest.h>
- using namespace std::string_literals;
- struct Base {
- virtual ~Base() = 0;
- };
- Base::~Base() {}
- template <typename... Args>
- class Factory {
- public:
- static Factory& get()
- {
- static Factory instance;
- return instance;
- }
- template <typename T>
- void reg(const std::string& name)
- {
- auto it = stock.find(name);
- if (it != stock.end()) {
- throw std::invalid_argument(name + " has been registered: " + __PRETTY_FUNCTION__);
- }
- stock[name].reset(new Creator<T>);
- }
- std::unique_ptr<Base> create(const std::string& name, Args&&... args)
- {
- auto it = stock.find(name);
- if (it == stock.end()) {
- throw std::invalid_argument("Cannot find "s + __PRETTY_FUNCTION__);
- // std::cout << "Cannot find " << __PRETTY_FUNCTION__ << '\n';
- // return nullptr;
- }
- std::cout << __PRETTY_FUNCTION__ << '\n';
- return it->second->create(std::forward<Args>(args)...);
- }
- private:
- struct ICreator {
- virtual std::unique_ptr<Base> create(Args&&...) = 0;
- virtual ~ICreator() = default;
- };
- template <typename T>
- struct Creator : public ICreator {
- virtual std::unique_ptr<Base> create(Args&&... args) override
- {
- return std::make_unique<T>(std::forward<Args>(args)...);
- }
- };
- std::unordered_map<std::string, std::unique_ptr<ICreator>> stock;
- };
- template <typename... Args>
- std::unique_ptr<Base> create(const std::string& name, Args&&... args)
- {
- return Factory<Args...>::get().create(name, std::forward<Args>(args)...);
- }
- template <typename T, typename... Args>
- class Register {
- public:
- explicit Register(const std::string& name)
- {
- Factory<Args...>::get().template reg<T>(name);
- }
- };
- struct A : public Base {
- inline static const Register<A, int> r1{"a"};
- inline static const Register<A, int, const std::string&> r2{"a"};
- inline static const Register<A, int, std::string&> r3{"a"};
- inline static const Register<A, int, std::string> r4{"a"};
- inline static const Register<A, int, const char*&> r5{"a"};
- explicit A(int a)
- {
- std::cout << "Creating A(" << a << ")\n";
- }
- A(int a, const std::string& s)
- {
- std::cout << "Creating A(" << a << ", " << s << ")\n";
- }
- };
- struct B : public Base {
- inline static const Register<B> r{"b"};
- // inline static Register<B> r2{"b"}; // abort at compile time
- B()
- {
- std::cout << "Creating B()\n";
- }
- };
- TEST(Factory, Simple)
- {
- ASSERT_TRUE(create("a", 1));
- ASSERT_TRUE(create("b"));
- }
- TEST(Factory, String)
- {
- ASSERT_TRUE(create("a", 2, "hi"s)); // Args = {int, std::string}
- }
- TEST(Factory, StringLvalue)
- {
- std::string s = "hi";
- ASSERT_TRUE(create("a", 3, s)); // Args = {int, std::string&}
- }
- TEST(Factory, ConstStringLvalue)
- {
- const std::string s = "hi";
- ASSERT_TRUE(create("a", 4, s)); // Args = {int, const std::string&}
- }
- TEST(Factory, ConstCharPtr)
- {
- const char* s = "hi";
- ASSERT_TRUE(create("a", 5, s)); // Args = {int, const char*&}
- }
- TEST(Factory, CharArray)
- {
- // Cannot find std::unique_ptr<Base> Factory<Args>::create(const string&, Args&& ...)
- // [with Args = {int, const char (&)[3]}]
- ASSERT_THROW(create("a", 6, "hi"), std::invalid_argument); // runtime error
- ASSERT_TRUE((create<int, std::string>("a", 7, "hi")));
- }
- TEST(Factory, InvalidParams)
- {
- ASSERT_THROW(create("b", 1), std::invalid_argument); // runtime error
- }
- int main(int argc, char** argv)
- {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
- }
复制代码
|
|