C++11 c++;11“专用”;“代理构造函数”;授权给私有的univeral引用构造函数?

C++11 c++;11“专用”;“代理构造函数”;授权给私有的univeral引用构造函数?,c++11,C++11,阅读Scott Meyer的书《有效的现代C++》,第24项(及以下)和第41项,我想知道这本书反对: 左值和右值参数的单个构造函数 到 模板化的通用构造函数解决方案 上面说,1。有重复代码的缺点 鉴于2。有可能被用于不需要的类型的缺点 我想知道为什么这本书没有提到一个混合模型——如下面所示的示例代码 它对左值和右值使用类型安全的专用构造函数,但将“通用引用”委托给单个(私有)泛型实现。 这避免了不必要的公共“通用引用”构造函数模板类型 那么下面的方法有什么问题吗?我错过了什么 #inc

阅读Scott Meyer的书《有效的现代C++》,第24项(及以下)和第41项,我想知道这本书反对:

  • 左值和右值参数的单个构造函数
  • 模板化的通用构造函数解决方案
  • 上面说,1。有重复代码的缺点
    鉴于2。有可能被用于不需要的类型的缺点

    我想知道为什么这本书没有提到一个混合模型——如下面所示的示例代码

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

    那么下面的方法有什么问题吗?我错过了什么

        #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;
        }
    
    #包括
    #包括
    类MyClass
    {
    私人:
    枚举类伪{Nop=0};
    模板
    MyClass(虚拟、T和数据)
    :_数据(标准::转发(数据))
    {
    
    std::cout现在让我们放下书,用正确的方式来做:

    优点:

  • 最佳效率

  • 正确的类型限制

  • 干的

  • 缺点:

  • 没有
  • -

    #包括
    #包括
    #包括
    类MyClass
    {
    公众:
    模板
    MyClass(T和数据)
    :_数据(标准::转发(数据))
    {
    
    std::cout现在让我们放下书,用正确的方式来做:

    优点:

  • 最佳效率

  • 正确的类型限制

  • 干的

  • 缺点:

  • 没有
  • -

    #包括
    #包括
    #包括
    类MyClass
    {
    公众:
    模板
    MyClass(T和数据)
    :_数据(标准::转发(数据))
    {
    
    std::请添加相关引用。避免从书中大量转储以避免版权问题。我假设实际问题本身就站得住脚;书中的上下文是否会修改它?我个人不理解他认为问题可能是什么。而且我手边没有这本书的副本,所以至少对我来说不,这个问题不站得住脚就其本身而言,代码示例并非出自书中。我实际上想知道,书中没有这样的(或类似的)。因此我问自己是否遗漏了一些内容。书中实际上讲述了这两种选择,但每种选择都有其优缺点。那么,上面的代码是充分利用了这两种选择的优点呢?还是存在其他一些普遍缺陷?您需要
    std::move(数据)
    在移动中。除此之外,我没有发现任何问题。请添加相关的引用。避免从书中大量转储以避免版权问题。我假设实际问题是独立的;书中的上下文是否会修改它?我个人不明白他认为问题可能是什么。而且我没有这本书的副本handy所以至少对我来说不,这个问题不是独立的代码示例不是来自书中。我真的很好奇,书中没有这样的(或类似的)因此,我问自己是否遗漏了什么。这本书实际上讲述了这两种选择,但每种选择都有其优点和缺点。那么,上面的代码是充分利用了这两种选择?还是有其他一些缺点?你需要在move-ctor上使用
    std::move(data)
    。除此之外,我看不到任何问题。
    #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);
    
    }