テンプレートを用いた関数のオーバーロードについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

テンプレートを用いた関数のオーバーロードについて

#1

投稿記事 by MoNoQLoREATOR » 14年前

突然ですが、下記のソースコードをコンパイルすると「4 オーバーロードのどれも、すべての引数の型を変換できませんでした」というエラーが出ます(160行目)。
► スポイラーを表示
これは、

コード:

addsize(string &input, long & size){ strinit(input, size); }
addsize(string &input){ strinit(input, -1); }
template <typename X>
addsize(X & address, long & size){ init(address, size); }
template <typename X>
addsize(X & address){ init(address, -1); }
この4つの内のどのコンストラクタを呼び出せば良いのか判断がつかないためにエラーになっているはずなのですが、どのように対処すれば良いのでしょうか?
bfileやbfilewクラスのメンバ関数では、テンプレートを使用しているものよりも型が明示されているものの方が優先的に呼び出され、エラーも出ないのですが、もしかしてコンストラクタの場合は駄目なのですか?

ご教授よろしくお願いいたします。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: テンプレートを用いた関数のオーバーロードについて

#2

投稿記事 by beatle » 14年前

MoNoQLoREATOR さんが書きました:bfileやbfilewクラスのメンバ関数では、テンプレートを使用しているものよりも型が明示されているものの方が優先的に呼び出され、エラーも出ないのですが、もしかしてコンストラクタの場合は駄目なのですか?
そんなことはないと思いますけど.
問題なのは,(int)にキャストしているのにint &型の引数に渡そうとしていることです.
int型のリテラルはint &型には渡せません.const int &型になら渡せます.

コード:

void f(int& i) {}
int main()
{
    int a;
    f(a); // OK
    f((int)a); // ERROR
}
ということですね.

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: テンプレートを用いた関数のオーバーロードについて

#3

投稿記事 by beatle » 14年前

それから,これは興味本位なのですが,どうして内容を変更しないのにlong &で受け取ろうとしているのでしょうか?

アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

Re: テンプレートを用いた関数のオーバーロードについて

#4

投稿記事 by MoNoQLoREATOR » 14年前

そこでしたか。ずっとテンプレートが原因だと思い込んで気づきませんでした。ありがとうございます。
"long"型に明示的にキャストすると自動的には"long &"型に変換してくれないのですね。
そして"unsigned long"型を"long"型には自動変換してくれるけど"long &"型には自動変換してくれない・・・と。
beatle さんが書きました:それから,これは興味本位なのですが,どうして内容を変更しないのにlong &で受け取ろうとしているのでしょうか?
addsizeは書き込み先のアドレスと書き込みサイズの情報を渡したい場合に<<演算子の右辺に渡します。さて、例えばバイナリデータを記録するとき、
「あるデータのデータサイズ」「あるデータ」
というように、読み込むべきデータのサイズをそのデータの前に置いておくことが多いのではないかと思います。
ということは先ほど読み込んだサイズをaddsizeの第2引数に指定したいという場面が多々生じるはずです。
しかしこのとき、某引数を単なる"long"型にしてしまうと、

コード:

	size_t num=0;
	int a[10];
	bfile f("text.txt");
	f >> num >> addsize(a, num);
などとした場合に、addsize(&c, num)の部分が先に翻訳されてしまい、読み込むべきデータサイズが初期値のまま(この場合0)になってしまいます。
そういった理由から、"long &"型となっています。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: テンプレートを用いた関数のオーバーロードについて

#5

投稿記事 by beatle » 14年前

キャストした時点で右辺値になりますから,左辺値を必要とするX &型の引数としては渡せません.

コード:

int i;
(int)i = 0; // ERROR
ということです.

アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

Re: テンプレートを用いた関数のオーバーロードについて

#6

投稿記事 by MoNoQLoREATOR » 14年前

・・・はて?
どこの箇所でそれが発生しますか?

ちなみに
(int)(i=0);
とすれば解決できると思うのですが、どうなのでしょう。

アバター
tk-xleader
記事: 158
登録日時: 15年前
連絡を取る:

Re: テンプレートを用いた関数のオーバーロードについて

#7

投稿記事 by tk-xleader » 14年前

>・・・はて?
>どこの箇所でそれが発生しますか?

型変換をするとその式は代入可能な左辺値ではなくて右辺値になります。ですから、

コード:

addsize( (string &)input, (long)unsint); //第二引数において、long&にlongの右辺値を渡そうとしている。
がエラーになるわけですが、これはすなわち

コード:

(int)i = 0; //(int)i は右辺値であるから、代入不可能
と本質的に同じエラーということです。
要は、constなしの参照は、代入可能な左辺値オブジェクトしか受け付けないのです。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

Re: テンプレートを用いた関数のオーバーロードについて

#8

投稿記事 by MoNoQLoREATOR » 14年前

なるほどそういうことでしたか。
大変お世話になりました。ありがとうございました。

閉鎖

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