【问题标题】:c++11 dedicated "proxy constructors" delegating to private univeral reference constructor?c ++ 11专用“代理构造函数”委托给私有通用引用构造函数?
【发布时间】:2016-07-13 08:29:59
【问题描述】:

阅读 Scott Meyer 的书《Effective Modern C++》,第 24 条(及以下)和第 41 条,我想知道这本书是否反对:

  1. 左值和右值参数的单独构造函数

  1. 模板化的通用构造函数解决方案

它说,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;
    }

【问题讨论】:

  • 请添加相关引号。避免从书中大量转储以避免版权问题。
  • 我认为实际问题是独立的;书中的上下文会修改它吗?
  • 我个人不明白他认为问题可能出在哪里。而且我手边没有这本书的副本,所以至少对我来说没有,这个问题并不独立
  • 代码示例不是来自本书。我实际上想知道,这样的(或类似的在书中不是)。因此,我问我是否遗漏了什么。这本书实际上讲述了这两种选择,但每种都有它的优点和缺点。那么上面的代码是否充分利用了它们?还是有其他普遍的缺陷?
  • 您需要 std::move(data) 移动 ctor。除此之外我没有发现任何问题。

标签: c++11


【解决方案1】:

现在让我们放下书,用正确的方式去做:

优点:

  1. 最佳效率

  2. 正确的类型限制

  3. 干燥

缺点:

-

#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);

}

【讨论】:

    猜你喜欢
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    相关资源
    最近更新 更多