返り値が複数欲しい関数

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

返り値が複数欲しい関数

#1

投稿記事 by Cr » 7年前

返り値が複数ほしいような関数って皆さんならどうしますか?
例えば二次平面の座標を求めるとか、xyの連立二元方程式を解くとか。
①複数のデータを構造体でまとめてそれを返り値にする
②vector<int>を返り値にする
③引数に答えを格納する用の変数を参照渡し
ぼくは基本上の3つのうちどれかを使ってます。
座標など構造体にしやすいのは①
集合同士の計算など、ある程度どの要素に対しても同じような計算をするとき②
①②のどちらでも無い時③
のような感じです。
皆さんのお勧めを教えてください。

アバター
SUE
記事: 41
登録日時: 7年前

Re: 返り値が複数欲しい関数

#2

投稿記事 by SUE » 7年前

基本的にはCrさんと同じ考え方ですかね。

ただし、値を直接変更してほしい変数を参照で渡すと、関数の中身だけ見てもコピーなのか参照なのか区別がつかなってちょっと危険なので、
void calc( int& in, int* out );みたいに入力→参照、出力→ポインタとやっています。
pop'n music 20 fantasia ポップンクエストPhase MAX Ⅱ ムラクモ/少年は空を辿る【Power Of Nature】

アバター
うしお
記事: 56
登録日時: 9年前

Re: 返り値が複数欲しい関数

#3

投稿記事 by うしお » 7年前

やはり名前の付けられる①がベターなんじゃないかと思います。
std::pair<>やboost::tupple,boost::tie()なんかを使って済ませることも可能といえば可能です。
しかし多用すると可読性が落ちるので、まだポインタで受け取って出力したほうがわかりやすいかと思います。
std::vectorはメモリの動的確保が入るため、数個の戻り値のために使うには少々無駄が多い気がします。
また、入力に参照を使うときはconst 参照がお勧めです。

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

Re: 返り値が複数欲しい関数

#4

投稿記事 by beatle » 7年前

STLのコンテナを戻り値にするのはコピーが発生して無駄,かといえば,C++11ではそうでもありません.右辺値参照がありますからね!

個人的に関数は,

コード:

結果 関数名(パラメータ)
という形が美しいと思います.

ということで,僕は基本的に1か2を選択します.
C++03しか使えないような状況でvector<int>を返したい場合など,戻り値のコピーコストが高い場合は,boost::shared_ptrで包んで返すこともあります.
まあ,上手く書けばRVOが働きますから,戻り値で戻しても効率は落ちなかったりしますけどね.

アバター
みけCAT
記事: 6225
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 返り値が複数欲しい関数

#5

投稿記事 by みけCAT » 7年前

言語が指定されていないので、C言語で考えます。
私は(3)’です。
答えを格納するための変数のポインタを渡します。
座標のxとyのように結果が2個くらいの時は、直接変数のポインタを渡します。
結果の数が多い場合、このコードのように、構造体のポインタを渡します。

…構造体の返り値ですか…
例えばサンプルとしてはこんな感じですね。

コード:

#include <stdio.h>
 
typedef struct {
        int a;
        int b;
} test_t;
 
test_t zikken(test_t tst) {
        test_t result;
        result.a=2*tst.a+3*tst.b;
        result.b=3*tst.a+2*tst.b;
        return result;
}
 
int main(void) {
        test_t testa;
        test_t testb;
        testa.a=5;
        testa.b=7;
        testb=zikken(testa);
        printf("%d %d\n",testb.a,testb.b);
        return 0;
}
http://ideone.com/2bUwD
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 1739
登録日時: 9年前

Re: 返り値が複数欲しい関数

#6

投稿記事 by box » 7年前

Cr さんが書きました:返り値が複数ほしいような関数って皆さんならどうしますか?
私は、時と場合によって複数の方法を使い分けます。
これ、と決め打ちすることはないです。たぶん。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
Cr
記事: 93
登録日時: 8年前

Re: 返り値が複数欲しい関数

#7

投稿記事 by Cr » 7年前

SUE さんが書きました:void calc( int& in, int* out );みたいに入力→参照、出力→ポインタとやっています。
良いですね 真似させてもらいます。
うしお さんが書きました:std::pair<>やboost::tupple,boost::tie()なんかを使って済ませることも可能といえば可能です。
しかし多用すると可読性が落ちるので、まだポインタで受け取って出力したほうがわかりやすいかと思います。
pair<>使ったこと無かったですねぇ…
機能自体は知っててもどこで使っていいのか分からない物がちょこちょこあるなぁ
stackとかも使ったこと無いし
ポインタの方が分かりやすいとのことですし、今後もあまり使う機会がなさそうです。
うしお さんが書きました:また、入力に参照を使うときはconst 参照がお勧めです。
真似させてもらいます。
beatle さんが書きました: 個人的に関数は,

コード:

 結果 関数名(パラメータ)
という形が美しいと思います.
うーむそうですか
再帰関数に③はむいてないんだよなぁ
beatle さんが書きました: まあ,上手く書けばRVOが働きますから,戻り値で戻しても効率は落ちなかったりしますけどね.
RVO、初耳でした。
コンパイラ依存らしいですけど名前つけても最適化されるNRVOなんてものもあるんですね
returnのところで名前をつけてない一次オブジェかぁ…
使う機会があったら使ってみます。
みけCAT さんが書きました: 座標のxとyのように結果が2個くらいの時は、直接変数のポインタを渡します。
結果の数が多い場合、このコードのように、構造体のポインタを渡します。
結構楽ですよね、それだと
構造体でポインタ渡したこと無かったかもしれません
構造体にすれば変数は一つになるんだし、じゃぁ返り値でいいやみたいな
この辺はもう好みなんですかね
box さんが書きました: 私は、時と場合によって複数の方法を使い分けます。
これ、と決め打ちすることはないです。たぶん。
なるほど…
あまりテンプレ化するのも良くないんですね
その場その場であってるものはどれか考えるのも大事ですね

解答してくださった方々、ありがとうございました。
結構知らない機能とかも出てきて良かったです。
いろいろな方法が聞けたので解決にしておきます。
どうもありがとうございました。

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: 返り値が複数欲しい関数

#8

投稿記事 by ISLe » 7年前

組み込みやってると戻り値はレジスタで返せる型を選びがちですね。
すぐにスタック溢れてしまうので。

閉鎖

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