コメントで述べたように、コンストラクター
std::vector<T> A{B.begin(), B.end()};
任意の 2 つのイテレータに対して機能するため、正常に機能するはずです。「異なるアロケーターが重要になるのはどの種類の STL 関数ですか?」という質問に関しては、2 種類の「異なる」があります。
- さまざまなタイプのアロケーター。
- 同じタイプのアロケーターですが、異なるものとして比較します。
(1) に関する非互換性については、型システムがキャッチするため、コンパイル時エラーが表示されるはずです。(2) については、STL 実装が潜在的な問題をキャッチするかどうかはわかりません。その点で心配する主なコンテナー/関数は、クラスのsplice
メソッドlist
(およびクラスのsplice_after
メソッドforward_list
) です。これは、あるコンテナーに割り当てられたオブジェクトを別のコンテナーに移動するためです。C++11 標準ノートの脚注 265 のように、STL コンテナーではアロケーターが等しいことが要求されるため、このような移動は問題になりません。
オフロードの問題に関しては、A がプレーンな STL アロケーターで割り当てられている場合、ホスト側で構築してコプロセッサー側で使用することはできません。ただし、B は両面で使用できます。これは、コプロセッサー側でB using an
offload::shared_allocator A`を構築する例です。, and constructs
#pragma offload_attribute (push, _Cilk_shared)
#include <vector>
#include "offload.h"
#include <cstdio>
#pragma offload_attribute (pop)
_Cilk_shared std::vector<int, __offload::shared_allocator<int> > B;
_Cilk_shared void foo() {
#ifdef __MIC__
std::vector<int> A(B.begin(),B.end());
for( auto& x: A )
std::printf("%d\n", x);
#else
std::printf("Host\n");
#endif
}
int main() {
auto y = 1;
for( int i=0; i<10; ++i ) {
B.push_back(y);
y *= 10;
}
_Cilk_offload foo();
}
次のように出力されます。
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000