c ++ 11专用“代理构造函数”委托给私有的通用参考构造函数? [英] c++11 dedicated "proxy constructors" delegating to private univeral reference constructor?

查看:168
本文介绍了c ++ 11专用“代理构造函数”委托给私有的通用参考构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. lvalue和rvalue参数的各个构造函数


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

不利于重复代码。

2.有一个缺点,可能用于不需要的类型。



我不知道为什么这本书没有提到 mixed 模型 - 如下面所示的示例代码。



它使用类型安全的专用构造函数为左值和右值,但委托给一个通用参考。
这种避免不需要的公共通用引用构造函数的模板类型。



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

  #include< iostream> 
#include< string>

class MyClass
{
private:

enum class Dummy {Nop = 0};

template< class T>
MyClass(Dummy,T&& amp; data)
:_data(std :: forward< T>(data))
{
std :: cout< MyClass universal reference template c'tor< std :: endl;
}

public:

//代理c'tors委托通用引用c'tor
MyClass(s​​td :: string const& data )
:MyClass(Dummy :: Nop,data)
{
std :: cout< MyClass lvalue c'tor< std :: endl;
}

MyClass(s​​td :: 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(s​​tr);
}

{
MyClass myClass(hello,world);
}

return 0;
}


解决方案


  1. 最佳效率


  2. 正确的类型限制



缺点:



-

  #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&& amp; data)
:_data(std :: forward< T>(data))
{
std :: cout< MyClass universal reference template c'tor< std :: endl;
}

private:

std :: string _data;

};

int main()
{
使用命名空间std :: string_literals;

auto a = MyClass(hellos);
auto b = MyClass(world);


const auto s =Hello,Worlds;
auto s2 =Hello,World;

auto c = MyClass(s​​);
auto d = MyClass(s​​2);

//不会编译
// auto e = MyClass(10);

}


Reading Scott Meyer's book "Effective Modern C++", Item 24 (and following), and Item 41, I wonder that this book opposes:

  1. the individual constructors for lvalue and rvalue parameters

to

  1. a template'd universal constructor solution

It says, that 1. has the disadvantage to duplicate code.
Whereas 2. has the disadvantage to potentially being used for unwanted types.

I wonder why the book does not mention a mixed model - as in the example code shown below.

It uses type-safe dedicated constructors for lvalue and rvalue but delegates to a single (private) generic implementation for "universal reference". This avoids unwanted template types of a public "universal reference" constructor.

So is there is anything wrong with the approach below? Something I missed?

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

解决方案

And now let's put the book down and do it the right way:

Pros:

  1. Optimal efficiency

  2. Correct type limitations

  3. DRY

Cons:

  1. None

-

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

}

这篇关于c ++ 11专用“代理构造函数”委托给私有的通用参考构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆