ページ 11

デフォルトコンストラクタが消えてない?

Posted: 2012年11月04日(日) 20:23
by ポケホーク
DxLibをクラス化しようと思い以下のコードを書きましたが...
デフォルトコンストラクタを消去しているはずなのにエラーが出ます。

コード:

//一部省略
class Window 
{
private:
	Window() = delete;
	Window(const Window &) = delete;
	Window &operator=(const Window &) = delete;
public:
	Window(const std::string &title = "DxLib", int width = 640, int height = 480)
	{
		DxLib::SetGraphMode(width, height, 0x10);
		DxLib::ChangeWindowMode(TRUE);
		DxLib::SetOutApplicationLogValidFlag(FALSE);
		DxLib::SetWindowText(title.c_str());
		if(DxLib::DxLib_Init() == -1)
		{
			throw DxError("Error in DxLib_Init");
		}
		DxLib::SetDrawScreen(DX_SCREEN_BACK);
	}
	~Window()
	{
		DxLib::DxLib_End();
	}
};
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	Window window;
	return 0;
};
test1.cpp: コンストラクタ 'Window::Window(const string&, int, int)' 内:
test1.cpp:19:39: エラー: 'DxError' was not declared in this scope
test1.cpp: 関数 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)' 内:
test1.cpp:30:9: エラー: オーバーロードされた 'Window()' の呼び出しは曖昧です
test1.cpp:30:9: 備考: 候補:
test1.cpp:11:2: 備考: Window::Window(const string&, int, int)
test1.cpp:7:2: 備考: Window::Window() <削除済み>
make[1]: *** [test1.o] Error 1
使用コンパイラはMinGWです。

Re: デフォルトコンストラクタが消えてない?

Posted: 2012年11月04日(日) 20:25
by ポケホーク
間違えました。
正しいエラー内容はこちらです。
test1.cpp: 関数 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)' 内:
test1.cpp:39:9: エラー: オーバーロードされた 'Window()' の呼び出しは曖昧です
test1.cpp:39:9: 備考: 候補:
test1.cpp:20:2: 備考: Window::Window(const string&, int, int)
test1.cpp:16:2: 備考: Window::Window() <削除済み>

Re: デフォルトコンストラクタが消えてない?

Posted: 2012年11月04日(日) 20:55
by h2so5
The definition form =delete; indicates that the function may not be used. However, all lookup and overload resolution occurs before the deleted definition is noted. That is, it is the definition that is deleted, not the symbol; overloads that resolve to that definition are ill-formed.
http://www.open-std.org/jtc1/sc22/wg21/ ... tml#delete から引用

delete は関数が使用されないことを明示するもので、
宣言自体が無効になるわけではなく、オーバーロードの解決には影響を与えないようです。

Re: デフォルトコンストラクタが消えてない?

Posted: 2012年11月04日(日) 20:56
by GRAM
①ユーザー定義のコンストラクタを定義している場合、コンストラクタをdeleted functionにすることは冗長です。
これは規格8.4.3のexampleにも書いてあります

これで動きます。

コード:

#include <iostream>
using namespace std;
 
struct Hoge
{
  Hoge( int i = 0 )
  {
      cout << "hoge.Constructor" << endl;
  }
};
 
 
int main()
{
    Hoge hoge;
}

②同じ個所にこう書いてあります
A program that refers to a deleted function implicitly or explicitly, other than to declare it, isill-formed.
明示的、非明示的を問わず、宣言を除いてdeleted function に言及するプログラムはill-formedである。
らしいです。

③deleted functionにはODRが適用されるみたいです。
今回の場合多分これに違反してます

ごめんなさい関係ないです

h2so5さんのいうとおり
deleted definitions はルックアップの候補になるみたいです。
オーバーロード解決の違反ですね

Re: デフォルトコンストラクタが消えてない?

Posted: 2012年11月04日(日) 21:15
by ポケホーク
回答ありがとうございます。
勉強になりました。