10

Visual Studio 2012RC には、非標準の拡張機能がいくつかあります。たとえば、このコードは次のようにコンパイルされます。

#include <string>

using namespace std;

void value(string& value)
{
    value = "some";
}

int main()
{
    value(string("nice"));
}

非標準の拡張子であるという警告が表示されます。それで、それがどのように現実のものであり、コードがどのように変換されるか(右辺値参照またはconst_castによるconst参照)を理解したいですか?

4

3 に答える 3

8

クラス型の一時オブジェクトは依然としてオブジェクトです。これはメモリ内のどこかに存在します。つまり、コンパイラが参照をアタッチできることに異常はありません。物理レベルでは、それが const 参照であるか非 const 参照であるかに違いはありません。つまり、そのような場合、言語の制限は純粋に概念的で人為的なものです。コンパイラはその制限を単に無視します。ここで何かを「変換」する必要はありません。参照は、そのオブジェクトがたまたま存在する場所であれば、そのオブジェクトに直接アタッチされるだけです。

基本的に、外部ワードにそのthisポインターの値へのアクセス (またはへの左辺値アクセス*this) を提供するクラスの場合、動作はすぐに簡単にシミュレートできます。

struct S {
  S& get_lvalue() { return *this; }
};

void foo(S& s);
...

foo(S().get_lvalue());

上記のコードは完全に合法であり、前述の制限を回避します。MSVC++ の動作はこれと同等と考えることができます。

于 2012-07-16T16:47:44.010 に答える
3

基本的に、VSはスペースをどこかに割り当て、constnessなしの参照(またはC ++ 11では右辺値参照)であるかのように、参照がそのスペースを指すようにします。const

この動作を無効にするには、/Za(言語拡張機能を無効にする)コンパイラスイッチを使用します。

プロパティ->C/C++->言語

もし私が正確に覚えていれば。

于 2012-07-16T16:42:19.570 に答える
3

string("nice")標準のC++では、一時(右辺値/ )を非定数参照(左辺値)にバインドすることはできませんが、Microsoftコンパイラでは許可されています。警告は、コードが拡張機能のためにコンパイルされており、他のコンパイラではコンパイルされないことを示しています。

于 2012-07-16T16:42:22.653 に答える