2

次の再作成可能な最小の標準準拠コードを検討してください

#include <vector>
#include <memory>
struct Foo
{
    int m_field1;
    Foo(int field1):m_field1(field1){};
};
typedef unsigned long DWORD;
typedef unsigned short WORD;
struct BitField {
    struct {
        DWORD   Field1:31;
        DWORD   Field2:1;
    } DUMMY;
};
int main()
{
    std::vector<std::shared_ptr<Foo>> bar;
    BitField *p = new BitField();
    //This Line compiles
    auto sp1 = std::shared_ptr<Foo>(new Foo((DWORD)p->DUMMY.Field1));
    //But std::make_shared fails to compile
    auto sp2 = std::make_shared<Foo>((DWORD)p->DUMMY.Field1);
    return 0;
}

このコードは、VC11 Update 2 でのコンパイルに失敗し、次のエラー メッセージが表示されます。

1>Source.cpp(23): error C2664: 'std::shared_ptr<_Ty> std::make_shared<Foo,DWORD&>(_V0_t)' : cannot convert parameter 1 from 'DWORD' to 'unsigned long &'
1>          with
1>          [
1>              _Ty=Foo,
1>              _V0_t=DWORD &
1>          ]

IDEONEをクロスチェックしたところ、正常にコンパイルされました。明らかな何かが欠けていますか?

接続バグが開かれましたhttps://connect.microsoft.com/VisualStudio/feedback/details/804888/with-language-extension-enabled-vc11-an-explicit-cast-is-not-creating-an-rvalue-from -ビットフィールド

4

4 に答える 4

9

これは奇妙なものです。次のスニペットは、/Za(言語拡張機能を無効にする) コンパイラ フラグの下でコンパイルされますが、フラグなしではコンパイルされません。

struct {
  unsigned field:1;
} dummy = {0};

template<class T>
void foo(T&&){}

int main(){
  foo((unsigned)dummy.field);
}

なしのエラー/Za:

エラー C2664: 'foo': パラメーター 1 を 'unsigned int' から 'unsigned int &' に変換できません

へのキャストは単純に右辺値を作成する必要があるため、これは明らかにバグです。これはunsigned、左辺値参照として推定されるべきではなく、ビットフィールドとして扱われるべきではありません。「rvalues bind to lvalue-references」の拡張がここで役割を果たすと感じています。

Microsoft Connect でバグ レポートを提出してください。

于 2013-10-08T20:18:13.880 に答える
2

コンパイラのエラー メッセージは、渡された値から を実際に作成できない限り、正しいものDWORD&です。ビットフィールドは、 への実際の参照として適切なサイズではありませんDWORD。コンパイラがあなたのプログラムを拒否するのが正しいかどうか、私にはわかりません。

ただし、回避するのは簡単です。を呼び出すときに、2 番目のテンプレート パラメータを指定するだけですmake_shared

auto sp2 = std::make_shared<Foo, int>(p->DUMMY.Field1);

intそれがコンストラクターの引数の型であるため、使用しました。DWORD代わりに言うことができます。おそらく非参照数値型で十分でしょう。その後、 への型キャストを放棄することもできますDWORD。それ以上何もしません。

于 2013-10-08T19:35:21.040 に答える