C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
こんた

C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

#1

投稿記事 by こんた » 5年前

コンテナクラスのlistにループ情報も加えたClistクラスを作り、そのコンストラクタを作っているのですが

コード:

template<class _Ty, class _Alloc = allocator<_Ty> > 
class Clist {
private:
	bool isLoop = false;
	list<_Ty> myList;

public:
	Clist() { myList = list<_Ty>; }
	Clist(bool loop, size_type _Count) { isLoop = loop; myList = list<_Ty>(_Count); }
	Clist(bool loop, size_type _Count, const _Ty& _Val) { isLoop = loop; myList = list<_Ty>(_Count, _Val); }

	template<class _Iter, class = typename enable_if<_Is_iterator<_Iter>::value, void>::type>
	Clist(bool loop, _Iter _First, _Iter _Last) { isLoop = loop; myList = list<_Ty>(_First, _Last); }

	Clist(const _Myt& _Right) { isLoop = _Right.isLoop; myList = list<_Ty>(_Right.myList); }
	Clist(bool loop, _XSTD initializer_list<_Ty> _Ilist, const _Alloc& _Al = allocator_type()) { isLoop = loop; myList = list<_Ty>(_Ilist, _Al); }
}
コードのように6つのコンストラクタを作ったのですが
例えば
Clist<int> first(true, { 1, 2, 3 });
Clist<int> second(first);
Clist<int> third({ 1, 2, 3 });
のようにするとfirstは6つめのコンストラクタが呼ばれ、secondは5つめのコピーコンストラクタが呼ばれ、ここまでは意図した通り動いてくれているのですが
thirdのようにした場合なぜかコンパイルが成功し、5つめのコピーコンストラクタが呼ばれてしまいます。
thirdのようにした場合はエラーがでるようにするにはどうすればいいでしょうか。よろしくお願いします。

アバター
nullptr
記事: 239
登録日時: 8年前

Re: C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

#2

投稿記事 by nullptr » 5年前

{ 1, 2, 3 }が_Mytに暗黙変換可能なのでしょう。_Mytの型がわからないのでそれしか言えません。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

こんた

Re: C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

#3

投稿記事 by こんた » 5年前

すみません。今回のコードに関係ありそうなtypedef書いておきます。

typedef Clist<_Ty, _Alloc> _Myt;
typedef list<_Ty, _Alloc> _Mybase;
typedef typename _Mybase::size_type size_type;
typedef typename _Mybase::value_type value_type;

よろしくお願いします。

アバター
nullptr
記事: 239
登録日時: 8年前

Re: C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

#4

投稿記事 by nullptr » 5年前

おっと、返信が遅れてすいません。忘れてました。
third({1,2,3})と書いた場合、コピーコンストラクタが呼ばれます。
コンパイラはおそらくthird(Clist{1,2,3})のように推論しているからです。
なぜ{ 1, 2, 3 }がClistに変換できると判断されるかというと、おそらく3番目のコンストラクタと一致すると判断されているのでしょう。1はboolに、2はsize_typeに、3は_Tyに暗黙変換されています。
これらの回避策は複数考えられますが、根本的にClistの暗黙変換を禁止するのが手っ取り早いと思います。
explicit Clist(bool loop, size_type _Count, const _Ty& _Val)
のように宣言して試してみて下さい。他のコンストラクタも暗黙変換を禁止しても良いと思います。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

こんた

Re: C++で意図しないコンストラクタが呼ばれるのを何とかしたいです

#5

投稿記事 by こんた » 5年前

返信ありがとうございます。
アドバイス通りexplicitをつけるとコンパイルエラーが出るようになりました。
ありがとうございました。

閉鎖

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