c ++ 11专用“代理构造函数”委托给私有univeral引用构造函数?

时间:2016-07-13 08:30:00

标签: c++11

阅读Scott Meyer的书“Effective Modern C ++”,Item 24(及以下)和Item 41,我不知道这本书是否反对:

  1. lvalue和rvalue参数的各个构造函数
    1. 模板的通用构造函数解决方案
    2. 它说,1.具有重复代码的缺点。
      而2.具有潜在用于不需要的类型的缺点。

      我想知道为什么这本书没有提及混合模型 - 如下面的示例代码所示。

      它为lvalue和rvalue使用类型安全的专用构造函数,但委托给“通用引用”的单个(私有)泛型实现。 这个避免了公共“通用引用”构造函数的不需要的模板类型。

      以下方法有什么问题吗?我错过了什么?

          #include <iostream>
          #include <string>
      
          class MyClass
          {
          private:
      
              enum class Dummy { Nop = 0 } ;
      
              template <class T>
              MyClass(Dummy, T&& data)
              : _data(std::forward<T>(data))
              {
                  std::cout << "MyClass universal reference template c'tor" << std::endl;
              }
      
          public:
      
              // proxy c'tors delegating to universal reference c'tor
              MyClass (std::string const & data)
              : MyClass(Dummy::Nop, data)
              {
                  std::cout << "MyClass lvalue c'tor" << std::endl;
              }
      
              MyClass (std::string && data)
              : MyClass(Dummy::Nop, std::move(data))
              {
                  std::cout << "MyClass rvalue c'tor" << std::endl;
              }
      
          private:
              std::string _data;
          };
      
          int main(int, char**)
          {
      
              {
                  std::string str("demo");
                  MyClass myClass(str);
              }
      
              {
                  MyClass myClass("hello, world");
              }
      
              return 0;
          }
      

1 个答案:

答案 0 :(得分:0)

现在让我们把书放下来并以正确的方式做到:

优点:

  1. 最佳效率

  2. 更正类型限制

  3. DRY

  4. 缺点:

    1. -

      #include <iostream>
      #include <string>
      #include <type_traits>
      
      class MyClass
      {
      
      public:
      
          template <class T, std::enable_if_t<std::is_constructible<std::string, T>::value>* = nullptr>
          MyClass(T&& data)
          : _data(std::forward<T>(data))
          {
              std::cout << "MyClass universal reference template c'tor" << std::endl;
          }
      
      private:
      
          std::string _data;
      
      };
      
      int main()
      {
          using namespace std::string_literals;
      
          auto a = MyClass("hello"s);
          auto b = MyClass("world");
      
      
          const auto s = "Hello, World"s;
          auto s2 = "Hello, World";
      
          auto c = MyClass(s);
          auto d = MyClass(s2);
      
      // won't compile
      //    auto e = MyClass(10);
      
      }