c ++ 11专用“代理构造函数”委托给私有的通用参考构造函数? [英] c++11 dedicated "proxy constructors" delegating to private univeral reference constructor?
问题描述
阅读Scott Meyer的书有效的现代C ++,项目24(和以下)和项目41,我不知道这本书反对:
- lvalue和rvalue参数的各个构造函数
到
- 模板的通用构造函数解决方案
不利于重复代码。
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(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;
}
-
最佳效率
-
正确的类型限制
-
缺点:
- 无
-
#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(s2);
//不会编译
// 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:
- the individual constructors for lvalue and rvalue parameters
to
- 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:
Optimal efficiency
Correct type limitations
DRY
Cons:
- 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屋!