返回仅移动自由函数与成员函数的类型

时间:2014-04-27 14:45:14

标签: c++ c++11 return-value

首先让我简要介绍一下实际情况:

我创建了一个名为error<T>的类模板,它保存了类型T和与错误相关的变量 构造函数就像这样

error(T&&,..other_params...)   

并且有一个生成函数的实用程序函数,其定义如此

template<typename T>
make_error(T&& val_T,..other_params..)
{return error<T>(std::forward<T&&>(val_t),..other_params..);}

我使用此类型作为返回类型而不仅仅是类型T.基本上它只是包含错误信息的类型。

它有一个getter,它获取包含类型的值:

T get()
{ return val_T_int;}

其中val_T_int与上面的val_t有关 当我使用仅移动类型时,此get会出现错误delete copy constructor being used

Q1。为什么会这样说?为什么不移动构造值?即我必须在返回值上明确使用std :: move()。

Q2。如果Q1不可能那么我将如何启用这样的功能,而用户而不是返回类型将返回此错误.i无法使用boost::optional,因为它需要类型为copy constructible

我的编译器:Windows 7上的minGW GCC 4.8.2。

例如:

class B //a move only type
{
    B( const B& )=delete;
    B& operator=( const B& ) = delete;
public:
    B( B&& )
    {
        std::cout << "B&&\n";
    }

    B& operator=( B&& )
    {
        std::cout << "B=\n";
            return *this; 
    }
    B(){ std::cout << "B()\n"; }
};

struct error  //the other parts are stripped of for simplicity.
{
    B get()
    {
        return std::move(b);
    }
private :
    B b{};// B is a move only type.
};

error er{};
er.get(); //error:use of deleted function B(const B&)!.

我在这里不理解什么? 谢谢你的阅读。

P.S this很接近,但我不明白局部变量的原因。

thisthis也提示帮助

2 个答案:

答案 0 :(得分:1)

您的get()想要返回一份副本,因此需要copy-ctor。如果您将内部值val_T_int移至返回值,则表示val_T_int无效。之后你无法访问它的值,这可能不是你想要的。

想到一个解决方案:不要返回值,只允许(const)访问:

const T& get() const
{
    return val_T_int;
}

如果您还需要/需要非const访问,请添加第二个重载:

T& get()
{
    return val_T_int;
}

允许您班级的用户甚至修改val_T_int,例如er.get() = 42;

答案 1 :(得分:1)

看看以下代码。如果get方法会将字符串移出成员变量,那么t的值应该是多少?

error e = make_error(std::string{"foobar"});
std::string s = e.get();
std::string t = e.get();

您可以返回对成员变量的引用。它可能如下所示:

const T& get() const { return val_T_int; }

该解决方案的问题在于,您无法通过以下方式将其与不可复制类型一起使用:

std::unique_ptr<...> result = make_error(...).get();

但是,您可以使用 rvalue-referenced for this 来解决此问题。如果以下列方式声明get,则该函数只能用于 temporaries (以及显式移动的对象)。因此,将成员变量移出对象是可以的。

T get() && { return std::move(val_T_int); }