ページ 1 / 1
template<typename T>を用いた引数の省略
Posted: 2013年2月23日(土) 20:47
by bonbo
早速ですが質問させていただきます。
関数の、template Tを使った引数を省略できるように改良したいと思い、以下のようなプログラムを組んだのですが
エラーが出ます。どこがいけないのでしょうか。
コード:
//プロトタイプ宣言
template<typename T>
void BeZero(int a,T& _data);
コード:
//内容を定義
template<typename T>
void BeZero(int a,T& _data=(T&)0){//こんな風に省略したい
_data=0;
}
コード:
//呼び出す
int main(void){
BeZero(1);//エラーが出る
return 0;
}
宣言と定義まではエラーが出ないのですが、呼び出すとエラーが出ます。
環境はXcode4.4ですが、VSでもできないのでVS2010です。
よろしくお願いします。
Re: template<typename T>を用いた引数の省略
Posted: 2013年2月23日(土) 21:44
by softya(ソフト屋)
テンプレート関数でテンプレート引数省略は無理では?
コンパイル時に確定すべきことが確定出来ないので、オブジェクトファイルを作り出せないと思います。
【補足】
C++11から関数テンプレートに対するデフォルトテンプレート引数が使えるようになったみたいです。
書き方は、こちら。
http://d.hatena.ne.jp/gintenlabo/20110302/1299093091
ただし、対応しているコンパイラが必要です。
Re: template<typename T>を用いた引数の省略
Posted: 2013年2月23日(土) 21:56
by h2so5
そもそも 0 を参照型にキャストしている時点で問題だと思います。
C++11のデフォルトテンプレート引数とポインタを使って書くならこうなります。
コード:
template<typename T = int>
void BeZero(int a, T* const _data = nullptr){
if (_data) *_data = 0;
}
Re: template<typename T>を用いた引数の省略
Posted: 2013年2月24日(日) 07:19
by bonbo
>softyaさん
ありがとうございます。
>テンプレート関数でテンプレート引数省略は無理では?
>コンパイル時に確定すべきことが確定出来ないので、オブジェクトファイルを作り出せないと思います。
あらかじめできるようには作っていないのですね。
リンク先の多重定義により解決する方法でできるならそちらでもやってみます。
>h2so5さん
ありがとうございます。
>c++11
VS2010では対応してないみたいですね…残念です。
http://posaune.hatenablog.com/entry/20120225/1330144337
ここにXcodeをC++0xに対応させる方法も書いてあるみたいです。
1年前の記事だからもうすでに対応してるかもしれませんね。
いろいろ教えていただいたので試してみます。
Re: template<typename T>を用いた引数の省略
Posted: 2013年2月24日(日) 09:54
by softya(ソフト屋)
1つは、0を参照しているのでこれは出来ません。
もう1つは「あらかじめできるようには作っていないのですね。
リンク先の多重定義により解決する方法でできるならそちらでもやってみます。」に関してですが、
動的に不定の型を処理する機械語(オブジェクト)を作り出せる仕様構造を静的型付け言語であるC++はもっていません。
高速性を犠牲にするので、C++の存在理由に反すると私は思います。
そういうのはインタプリタ・スクリプトの動的型付け言語が得意とするものです。
コンパイル時に型やアドレスを確定させてやることが出来るC++11の書き方であれば省略時の機械語(オブジェクト)が作り出せます。
Re: template<typename T>を用いた引数の省略
Posted: 2013年2月25日(月) 18:28
by bonbo
>softyaさん
ありがとうございます。
>高速性を犠牲にするので、C++の存在理由に反する
なるほど…
C++11からの文法を使うと2011年以前にリリースされたiOSで動かないのではないか…と不安だったので
使うのが怖かったのです…
C++11を使うことでできました。
一応やったことをまとめておくと、
Xcodeの設定を変えて(
http://posaune.hatenablog.com/entry/20120225/1330144337)
h2so5さんのおっしゃった
コード:
template<typename T = int>
void BeZero(int a, T* const _data = nullptr){
if (_data) *_data = 0;
}
このコードにならって修正していく
ということをやりました。
※Xcodeのデフォルトの設定からC++11の設定へと変えると、
最初はいろいろエラーが起こりますが、すべて修正を示唆してくれるエラーなのでその通りに直していけば動くみたいです。
(今回はGLubyte型の変数の初期化などで型キャストする必要がありました。エラーの指摘が厳しくなったみたいです。)
まだ気になる点があるのでまた別途質問します。
どうもありがとうございました。