Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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++_Casting_Rvalue Reference - Fatal编程技术网

C++ C+的意外行为+;某些类型的右值和左值实例的类型转换运算符

C++ C+的意外行为+;某些类型的右值和左值实例的类型转换运算符,c++,casting,rvalue-reference,C++,Casting,Rvalue Reference,我有一个关于某些类型的强制转换运算符的问题,该类型的实际实例的重载为右值和左值。我把我的问题放在代码示例中,在那里我期望得到的不是实际结果 也许有人能告诉我为什么它是这样做的 #include <iostream> #include <vector> using namespace std; struct Foo { std::vector<int> m_value; Foo & add(int i) {

我有一个关于某些类型的强制转换运算符的问题,该类型的实际实例的重载为右值和左值。我把我的问题放在代码示例中,在那里我期望得到的不是实际结果

也许有人能告诉我为什么它是这样做的

#include <iostream>
#include <vector>

using namespace std;

struct Foo
{
    std::vector<int> m_value;

    Foo & add(int i)
    {
        m_value.emplace_back(i);
    }
    std::vector<int> const & get() const &
    {
        std::cout << "lvalue cast\n";
        return m_value;
    }
    std::vector<int> get() &&
    {
        std::cout << "rvalue cast\n";
        return std::move(m_value);
    }

    operator std::vector<int> const &() const &
    {
        std::cout << "lvalue cast\n";
        return m_value;
    }
    operator std::vector<int>() &&
    {
        std::cout << "rvalue cast\n";
        return std::move(m_value);
    }
};

Foo make_foo()
{
    Foo ret;
    ret.m_value.emplace_back(0);
    ret.m_value.emplace_back(1);
    return ret;
}

int main() {
    { // cast
        std::cout << "cast operator\n";
        Foo foo = make_foo();
        std::vector<int> foo_rvalue = make_foo(); // rvalue cast
        std::vector<int> const & foo_lvalue = foo; // lvalue cast
        std::vector<int> foo_move_assign;
        //foo_move_assign = std::move(foo); // ambigous or lvalue cast (onlinegdb.com), but I expected rvalue cast
        std::vector<int> foo_move_ctor = std::move(foo); // rvalue cast
        std::vector<int> const &foo_move_to_cref = std::move(foo); // lvalue cast, but I expected rvalue cast
    }
    { // get
        std::cout << "get method\n";
        Foo foo = make_foo();
        std::vector<int> foo_rvalue = make_foo().get(); // rvalue cast
        std::vector<int> const & foo_lvalue = foo.get(); // lvalue cast
        std::vector<int> foo_move_assign;
        foo_move_assign = std::move(foo).get(); // rvalue cast
        std::vector<int> foo_move_ctor = std::move(foo).get(); // rvalue cast
        std::vector<int> const &foo_move_to_cref = std::move(foo).get(); // rvalue cast
    }
    return 0;
}
#包括
#包括
使用名称空间std;
结构Foo
{
std::向量m_值;
Foo&add(inti)
{
m_值。回装(i);
}
std::vector const&get()const&
{

std::coutstatic_cast
取消移动的效果。下面是如何实现std::move等效的方法:

static_cast<typename std::remove_reference<T>::type&&>(t)
static_cast(t)
您正在做的是将其回滚:

static_cast<T>(static_cast<typename std::remove_reference_t<T>&&>(t))
static_cast(static_cast(t))
发件人:

static_cast(expression)返回假想变量Temp,就像由new_type Temp(expression)初始化一样

这个虚构的变量Temp是一个值类型(不是引用),它有一个名称(它是一个变量),因此我认为它不能像建议的那样工作

至于如何让它像你期望的那样工作?这种隐式转换是邪恶的,我想目前你能做的最好的事情是:

struct Foo
{
    std::vector<int> m_value;

    operator std::vector<int>() const &
    {
        std::cout << "lvalue cast\n";
        return m_value;
    }
    operator std::vector<int>() &&
    {
        std::cout << "rvalue cast\n";
        return std::move(m_value);
    }
};
structfoo
{
std::向量m_值;
运算符std::vector()常量&
{

std::我能在第一种情况下观察到不同的效果吗?一个不明确的重载:。此外,
foo\u move\u assign=std::move(foo)。操作符std::vector();
起作用:
foo\u move\u assign=std::move(foo)。操作符std::vector const&()
也可以工作。有趣的是,gdb不是CPMPlaning…显式指定运算符实际上在实践中是不可行的,我想说。这应该由编译器正确推导出来,还是我遗漏了什么?顺便说一句,注意,即使对于
Foo
类型的右值,也可能会调用第一个转换运算符,因此,对于
std::move(foo)
。常量l值引用始终可以绑定右值和左值。如果同时提供两个覆盖项,右值引用将对右值具有更高的优先级。但是,在您的情况下,没有重载。您有两个不同的强制转换运算符(针对不同的类型)。我猜这就是歧义的来源。请检查此情况:。如果将第一个强制转换运算符也更改为“plain”
int
,它开始按预期工作。好的,我添加这一点是因为@Daniel Langr的提示。你知道为什么没有强制转换它是不明确的。我本以为在std::move foo之后是一个右值引用,因此使用强制转换操作符的右值变体。。。