使用显式构造函数返回不可复制的不可移动对象 [英] Returning non-copyable non-movable object with explicit constructor

查看:87
本文介绍了使用显式构造函数返回不可复制的不可移动对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们有一个带有非显式构造函数的不可移动,不可复制的类,我们可以将其返回并按如下方式使用(在C ++ 11中):

  #include< iostream> 
类NonCop
{
public:
/ *非显式* / NonCop(int a,int b):number(a + b){}
NonCop( const NonCop&)= delete;
个整数;
};

NonCop get_non_cop()
{
return {1,2};
}

int main()
{
NonCop& nc = get_non_cop();
std :: cout<< 三:<< nc.number<< std :: endl;
返回0;
}

但是,如果构造函数是显式的,则无法使用。在C ++ 11 / C ++ 14中是否有任何方法可以在 NonCop 中进行任何修改?



当前,我正在使用从NonCop派生出具有包装程序的变态构造器的解决方法,但它看起来不是很漂亮。

解决方案

否,这是不可能的。从C ++ 11或14中的函数返回而没有隐式移动或复制(编译器肯定会退出)时,没有机制可以调用显式构造函数。



在C ++ 17中,您只需键入 return NonCop(1,2); ,由于保证省略,它不再需要移动或复制构造函数。 / p>




但这是C ++,所以是的,我可以使您的代码以零额外开销运行。通过作弊并返回其他类型。

  template< class T> 
struct hidden_​​construct:T {
template< class ... Ts>
hidden_​​construct(Ts& ... ts):
T(std :: forward< Ts>(ts)...)//注意:这是一个EXPLICIT构造
{ }
};

hidden_​​construct< NonCop> get_non_cop()
{
return {1,2};
}

实时示例



An implicit_construct< NonCop> 源自 NonCop ,因此您可以将返回值存储在 NonCop& 中。






如果您自己写的是 NonCop ,那么我要做的就是添加:

  structexplicit_construct_t {}; 
// ...
struct NonCop {
// ...
template< class ... Ts>
NonCop(explicit_construct_t,Ts& amp; ... ts):
NonCop(std :: forward< Ts>(ts)...)
{}
// ...
};

这意味着您可以在显式构造函数的前面加上 explicit_construct_t 隐式调用它们:

  NonCop get_non_cop(){
return {explicit_construct_t {},1 ,2};
}


If we have a non-movable, non-copyable class with non-explicit constructor, we can return it and use as follows (in C++11):

#include <iostream>
class NonCop
{
public:
    /*non explicit*/ NonCop(int a, int b) : number(a + b) {}
    NonCop(const NonCop&) = delete;
    int number;
};

NonCop get_non_cop()
{
    return {1, 2};
}

int main()
{
    NonCop &&nc = get_non_cop();
    std::cout << "three: " << nc.number << std::endl;
    return 0;
}

However if the constructor is explicit, it doesn't work. Is there any method of doing this in C++11/C++14 with no modifications in NonCop?

Currently I'm using workaround with deriving from NonCop with wrapper that "deexplicits" the constructor but it doesn't seem very pretty.

解决方案

No, this isn't possible. There is no mechanism to call explicit constructors while returning from a function in C++11 or 14 without having an implicit move or copy (that the compiler will certainly elide).

In C++17 you can just type return NonCop(1,2); and due to "guaranteed elision" it will no longer require a move or copy constructor.


But this is C++, so yes, I can make your code work with zero additional overhead. By cheating, and returning a different type.

template<class T>
struct implicit_construct:T {
  template<class...Ts>
  implicit_construct(Ts&&...ts):
    T(std::forward<Ts>(ts)...) // note: this is an EXPLICIT construction
  {}
};

implicit_construct<NonCop> get_non_cop()
{
  return {1, 2};
}

Live example.

An implicit_construct<NonCop> derives from a NonCop, so you can store the return value in a NonCop&&.


If you are writing NonCop yourself, then what I'd do is add:

 struct explicit_construct_t {};
 // ...
 struct NonCop {
   // ...
   template<class...Ts>
   NonCop( explicit_construct_t, Ts&&...ts ):
     NonCop( std::forward<Ts>(ts)... )
  {}
  // ...
};

which means you can call explicit constructors by prefixing it with a explicit_construct_t to call them implicitly:

NonCop get_non_cop() {
  return {explicit_construct_t{}, 1, 2};
}

这篇关于使用显式构造函数返回不可复制的不可移动对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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