質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

1回答

1609閲覧

C++でC配列からディープコピーせずにstd::vectorを作りたい

Gustave

総合スコア21

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/11/27 03:19

C++17環境です.
Cで作られたプロジェクトからC++で作られた外部ライブラリをコールするためにCの配列とstd::vectorを行ったり来たりする必要があります

現状ではC配列とstd::vectorへの相互変換がdeep copyになってしまっています
実行速度やメモリ量が無駄なのでstd::vectorの参照するポインタを変更したいのですが、良い方法はないでしょうか

イメージとしては以下のようなプログラムです

cpp

1void external_lib_func(&std::vector<int> vec); //これは外部のライブラリなので変更できない 2 3void func(int* d, size){ //この関数のAPIをstd::vectorに変更はできない 4 std::vector<int> vec_d(size); //これは無駄 5 6 for(size_t i = 0; i<所定の回数; i++){ 7 // Cで書かれた色々な処理によってdが変更される // 8 9 // ここでC配列 -> std::vectorへ変換するためにdeep copyが必要 10 for(size_t j = 0; j < size; j++){ 11 vec_d[i] = d[i]; 12 } 13 14 external_lib_func(vec_d); //vec_dが変更される 15 16 // std::vecor -> C配列も同様 17 for(size_t j = 0; j < size; j++){ 18 d[i] = vec_d[i]; 19 } 20  21 // Cで書かれた色々な処理によってdが変更される // 22 } 23}

全部std::vectorに変えれば上手くいくことは分かっているのですが、この func() 関数はFortranからも呼び出されているため難しいのが現状です

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki23

2021/11/27 03:47

> 実行速度やメモリ量が無駄なのでstd::vectorの参照するポインタを変更したいのですが、良い方法はないでしょうか それは不可能なので、質問を変えてもらえますか? 「この関数を効率的にするにはどうすればいいですか」とか
episteme

2021/11/27 03:52

std::vector を C配列に見せかけるのは簡単だけど 逆は無理。
Gustave

2021/11/27 05:52

> 「この関数を効率的にするにはどうすればいいですか」とか どちらかというと計算時間よりメモリのほうが厳しいのですが、質問を変更して解決策はありそうでしょうか?
Gustave

2021/11/27 06:39

> std::to_array で std::array に変換できるようです ありがとうございます Clangなのでまだ対応していないようですが、長期的に使うコードなので、頭に留めておきます
yominet

2021/11/27 07:12 編集

vectorではないことはとりあえずおいといて・・・ to_arrayは変換ではなく作成してしまうヤツだったかと
yuki23

2021/11/27 08:27

質問を変更して解決策があるかは、どのように変えるかによりますが、少なくとも今の質問(ディープコピーしか出来ないものをディープコピーしたくない)は本質的ではないので建設的な回答は難しいですね。
Gustave

2021/11/27 09:51

わかりました たくさんレスを貰っていますし、できないという回答も回答として重要だと思うので、この質問はこの質問として、どこまで許容するかも踏まえて考えて別の質問にします
guest

回答1

0

allocator を自前で用意して、配列の先頭アドレスを渡せばよいのではありませんか?

C++

1#include <iostream> 2#include <vector> 3 4void external_lib_func(std::vector<int>& vec) 5{ 6 for (int& e : vec) e++; 7} 8 9int *gp; 10 11template <typename T> 12struct Alloc { 13 typedef T value_type; 14 Alloc(T* p) { gp = p; } 15 T* allocate(size_t num) { return gp; } 16 void deallocate(T* p, size_t num) { } 17 void construct(T* p, const T& value) { } 18 void destroy(T* p) { } 19}; 20 21void func(int d[], size_t size) 22{ 23 std::vector<int, Alloc<int>> v(size, 0, Alloc<int>(d)); 24 25 for (size_t i = 0; i < 2; i++) { 26 d[i] = -d[i]; 27 external_lib_func(reinterpret_cast<std::vector<int>&>(v)); 28 d[i] *= 2; 29 } 30} 31 32int main() 33{ 34 int a[] = { 3, 1, 4, 2 }; 35 for (int e : a) std::cout << e << ' '; 36 std::cout << '\n'; 37 func(a, 4); 38 for (int e : a) std::cout << e << ' '; 39 std::cout << '\n'; 40}

私もよく分かっていなくて、reinterpret_cast を使ったり、
グローバル変数を使ったりしています。

投稿2021/11/27 07:23

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問