VS2010中的条件运算符正确行为?

Wal*_*rey 3 c++ visual-studio-2010 visual-c++

我想知道这段代码是否表现出正确的C++行为?

class Foo
{
public:
    Foo(std::string name) : m_name(name) {}

    Foo(const Foo& other) { 
        std::cout << "in copy constructor:" << other.GetName() << std::endl;
        m_name = other.GetName();
    }

    std::string GetName() const { return m_name; }
    void SetName(std::string name) { m_name = name; }

private:
    std::string m_name;
};

Foo CreateFoo(std::string name)
{
    Foo result(name);
    return result;
}

void ChangeName(Foo& foo)
{
    foo.SetName("foofoo");
}

int _tmain(int argc, _TCHAR* argv[])
{
    Foo fooA("alan");
    std::cout << "fooA name: " << fooA.GetName() << std::endl;
    bool b = true;
    ChangeName(b ? fooA : CreateFoo("fooB"));
    std::cout << "fooA name: " << fooA.GetName() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在VS2008中内置时,输出为:

fooA name: alan
fooA name: foofoo
Run Code Online (Sandbox Code Playgroud)

但是当在VS2010中构建相同的代码时,它变为:

fooA name: alan
in copy constructor: alan
fooA name: alan
Run Code Online (Sandbox Code Playgroud)

正在"alan"上调用复制构造函数,尽管通过引用传递(或者不是视情况而定),但fooA在被调用时未被更改ChangeName.

C++标准是否已更改,Microsoft是否修正了不正确的行为或是否引入了错误?

顺便说一句,为什么要调用复制构造函数

Edw*_*nge 5

更全面的答案:

5.16/4和5:

"4如果第二个和第三个操作数是左值并且具有相同的类型,则结果属于该类型并且是左值.

5否则结果是右值......"

换句话说,"bool?lvalue:rvalue"会导致暂时的.

这将是它的结束,但是你将它传递给一个函数,根据C++,它必须接收一个左值作为参数.因为你传递了一个rvalue,你实际上拥有的代码不是C++.MSVC++接受它,因为它是愚蠢的,并使用一堆它没有告诉你的扩展,除非你把它变成一个挂件.既然你所拥有的不是标准的C++,并且MS只是通过扩展允许它,那么关于它的"正确"再也没有什么可说的了.