[c++]visual studioの拡張機能とムーブコンストラクタについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
K_Tarou
記事: 22
登録日時: 12年前

[c++]visual studioの拡張機能とムーブコンストラクタについて

#1

投稿記事 by K_Tarou » 11年前

お世話になっております。
私は "Visual Studio c++ 2010 Express" を使用しているのですが、
ネット上で、 "独自の拡張機能はオフにした方が良い" ということが書かれていたのでオフにしました。
そうしてプログラムを書いていると、それまでエラーが出なかった、ムーブコンストラクタ呼び出しの記述でエラーが出るようになってしまいました。

質問の内容といたしましては、
以下の記述が、 " 環境独自の拡張機能を使わなければ許されないような記述 " なのかどうかを教えて頂きたいというものです。

コード:

MyClass obj = createClass();  //createClassは、MyClassクラスのオブジェクトを返す関数
上記のような記述や、 " MyClass obj = MyClass(...); " のような記述は
(最適化されないと考えた時は) テンポラリオブジェクト (右辺値) を作って、それで左辺のオブジェクトを初期化すると思うのですが、
この時、コピーコンストラクタが隠されている場合にはエラーになるのが、正しい挙動なのでしょうか?


例えば、下記のコードは、"Visual Studio 2010 Express" (言語拡張機能オフ) では "privateメンバーにアクセスできません" というエラーが出てしまいます。
コピーコンストラクタが、private指定されているためだと思うのですが、文脈から考えてコピーコンストラクタにアクセスする必要がないように感じます。
言語の拡張機能をオンにすると何事もなかったように実行できました。(volatile は無視されるという警告は出ましたが...)

コピーコンストラクタではなく、ムーブコンストラクタが呼ばれることを期待しているのですが、拡張機能をオフにした状態で正しく呼ぶにはどうしたらよいのでしょうか?

コード:

/* ムーブコンストラクタを持つクラス */
class Test{
public:
	Test() : m_num(0) {};
	explicit Test(int num) : m_num(num){};
	Test(Test&& obj);
private:
	int m_num;
	Test(const Test& obj);
};


/* ムーブコンストラクタの定義 */
Test::Test( Test&& obj){
	this->m_num = obj.m_num;
	obj.m_num = -999;
}


/* クラスを作成する関数 */
template<typename TYPE>
TYPE create(int arg){
	return TYPE(arg);
}


int main(){

	volatile Test obj1 = static_cast<volatile Test>( create<Test>(10) );

	volatile Test obj2 = static_cast<volatile Test>( Test(20) );

	return 0;
}

naohiro19
記事: 256
登録日時: 14年前
住所: 愛知県

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#2

投稿記事 by naohiro19 » 11年前

Visual Studio 2005/2008ではビルド不可能でしたね。

コード:

コンパイルしています...
main.cpp
main.cpp(10) : warning C4521: 'Test' : 複数のコピー コンストラクタが指定されています。
main.cpp(14) : error C2143: 構文エラー : ')' が '&&' の前にありません。
main.cpp(14) : error C2143: 構文エラー : ';' が '&&' の前にありません。
main.cpp(14) : error C2761: '{ctor}' : メンバ関数の再宣言はできません。
main.cpp(14) : error C2059: 構文エラー : ')'
main.cpp(14) : error C2143: 構文エラー : ';' が '{' の前にありません。
main.cpp(14) : error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?)
main.cpp(29) : warning C4197: 'volatile Test' : キャストの トップレベルの volatile は無視されます。
main.cpp(29) : error C2248: 'Test::Test' : private メンバ (クラス 'Test' で宣言されている) にアクセスできません。
        main.cpp(9) : 'Test::Test' の宣言を確認してください。
        main.cpp(2) : 'Test' の宣言を確認してください。
main.cpp(29) : error C2248: 'Test::Test' : private メンバ (クラス 'Test' で宣言されている) にアクセスできません。
       main.cpp(9) : 'Test::Test' の宣言を確認してください。
        main.cpp(2) : 'Test' の宣言を確認してください。



K_Tarou
記事: 22
登録日時: 12年前

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#3

投稿記事 by K_Tarou » 11年前

naohiro19さん
ご回答頂き、ありがとうございます。
2010以前のVCでもエラーになるのですね。態々調べて頂き、ありがとうございます。

関数の戻り値を返す際に、コピーコンストラクタが呼ばれるので、確かに隠ぺいされているとエラーになるのも分かるのですが、
最適化の関係で呼ばれない上に、右辺値が渡された時は適切にコンストラクタを呼び分けてくれるはずなのに
何故、コピーコンストラクタが呼べないというエラーになってしまうのでしょうか、いまいち理解できません。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#4

投稿記事 by h2so5 » 11年前

Visual Studioのバグが原因です。本来は拡張機能を使わない場合でもムーブコンストラクタが呼ばれるはずです。
VC++の開発者は、バグるので拡張機能をオフにするなと言っています。
Unfortunately, /Za is buggy. It performs an elided-copy-constructor-accessibility check when it shouldn't (binding rvalue references doesn't invoke copy constructors, even theoretically). As a result, /Za should not be used.
http://stackoverflow.com/questions/2681 ... in-vc-2010

VC++ 2008でエラーになるのは単にムーブコンストラクタ自体をサポートしていないからです。

K_Tarou
記事: 22
登録日時: 12年前

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#5

投稿記事 by K_Tarou » 11年前

h2so5 さん
ご回答頂き、ありがとうございます。

Visual Studio のバグが関係していたとは全く考えておりませんでした。
一応、マイクロソフトのWebページ等を調べていたのですが、該当する情報を見つけられずに困っておりました。
バージョンの件につきましては、ご指摘して頂いた通り、単純にサポートの有無の問題だったようですね。
拡張機能は切らずにおくことにしました。

おかけで助かりました、ありがとうございます!

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#6

投稿記事 by h2so5 » 11年前

ちなみにVC++2012で確認したところこのバグは直っていましたので、そちらを使うという手もあります。

K_Tarou
記事: 22
登録日時: 12年前

Re: [c++]visual studioの拡張機能とムーブコンストラクタについて

#7

投稿記事 by K_Tarou » 11年前

h2so5 さん
態々、確認して頂きありがとうございます。
実は使用しているOSが WindowsXP でして、2010以降のVCが使えない状況なのです。
使用OSについても記述しておくべきでした、すいません。

ただ、結局は移行することになるのでバグが直っていることが確認できて安心できました。
重ねてお礼申し上げます、ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る