Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何禁止指定给临时对象和从其他类型隐式转换?_C++_C++11_Casting_Operators_Overloading - Fatal编程技术网

C++ 如何禁止指定给临时对象和从其他类型隐式转换?

C++ 如何禁止指定给临时对象和从其他类型隐式转换?,c++,c++11,casting,operators,overloading,C++,C++11,Casting,Operators,Overloading,对于普通对象和临时对象,I重载=运算符两次。 不幸的是,g++(Debian 4.7.2-5)4.7.2允许过多的临时对象。 例如,他不应该允许分配给临时对象。 他还允许将其他类型变量指定给对象 #include <cstdlib> #include <utility> #include <iostream> using namespace std; class Simple { int number; public: int getNumbe

对于普通对象和临时对象,I重载=运算符两次。 不幸的是,g++(Debian 4.7.2-5)4.7.2允许过多的临时对象。 例如,他不应该允许分配给临时对象。 他还允许将其他类型变量指定给对象

#include <cstdlib>
#include <utility>
#include <iostream>
using namespace std;
class Simple {
    int number;
public:
    int getNumber() const {
        return number;
    }
    Simple(const Simple& that) : number(that.number) {}
    Simple(Simple&& that) : number(move(that.getNumber())) {}
    Simple(int a) {number = a;}
    Simple& operator=(const Simple &base) {
        if (&base != this) {
            this->number = std::move(base.getNumber());
        }
        return *this;
    }
    Simple& operator=(Simple&& base) {
        if (&base != this) {
            this->number = std::move(base.getNumber());
        }
        return *this;
    }
};
Simple reverse(const Simple& base) {
    Simple result(base.getNumber());
    return result;
}
int main(int argc, char** argv) {
    Simple one(4);
    Simple two(5);
    one = two.getNumber();//This should be compile error.
    reverse(two) = one;This should be compile error.
    return 0;
}

我试图在运算符声明的末尾添加&&=delete,但编译器引发编译错误。我试图在类范围之外实现此运算符,但没有效果。

第一个问题是您是否真的希望维护代码以禁止这些情况。通常,对于类类型,允许将赋值给临时(右值),因为它调用任何其他成员函数。在C++11及以后版本中,对于右值引用,您可以在重载解析期间区分右值和左值,这可用于阻止对右值的赋值。要阻止
int
中的赋值,可以禁止所有隐式转换(我建议不要进行隐式转换)或阻止特定赋值运算符:

class Simple { 
// ...
    // Disallow implicit conversions from int
    explicit Simple(int);

    // Inhibit assignment to rvalues
    Simple& operator=(Simple const &) && = delete;

    // Alternatively, require that it is called on an lvalue
    Simple& operator=(Simple const &s) &;
    Simple& operator=(Simple &&) &;

    // ... or block assigment from 'int'
    Simple& operator=(int) = delete;
};

尽管说实话,我只会禁止隐式转换,而将其余部分留给类的用户。

您可以给出
Simple(int)
用于防止隐式转换的
显式
说明符,并使用赋值运算符的左值引用限定符来防止临时实例的赋值。要禁用隐式转换,请使构造函数
显式
。要禁用对临时变量的赋值,请提供
运算符=
一个
&
ref限定符。移动
int
也绝对没有意义。移动
int
没有什么意义,但是如果它不是int,那么从
const
对象移动应该会导致
Simple::operator=(const Simple&)中的编译时错误。
@Walter没有“从
const
对象移动”;
getNumber
的结果是一个prvalue,通过
std::move
传递它没有任何效果。@Casey从技术上讲,它将prvalue转换成xvalue:p编译器在成员函数上正确地实现了尾随的
&
&
。@Walter:我认为至少gcc和clang。最新的SunStudio编译器声称(尚未测试)完全支持C++11,XLC12.1声称支持右值引用(没有任何限定符,但它不完全…),VS2013可能(不知道,尚未测试)我如何实现:Simple&operator=(Simple const&s)&;简单&运算符=(简单&&)&@多曼迪尼奥:说清楚点,我不会这么做,我不相信这是你需要保护你的用户不受伤害的东西。也就是说,实现与您在问题中的实现是一样的。@DavidRodríguez dribeas我必须禁止分配给临时对象,因为这是我的老师交给我的任务的一部分。不幸的是,我无法实现这一点。您的帖子中没有一个解决方案被编译。也许我做错了什么,但我浪费了很多时间试图解决这个问题而没有效果。。。
class Simple { 
// ...
    // Disallow implicit conversions from int
    explicit Simple(int);

    // Inhibit assignment to rvalues
    Simple& operator=(Simple const &) && = delete;

    // Alternatively, require that it is called on an lvalue
    Simple& operator=(Simple const &s) &;
    Simple& operator=(Simple &&) &;

    // ... or block assigment from 'int'
    Simple& operator=(int) = delete;
};