私は自己がこの機能を何度も果たすタイプを識別しなければならないことが分かりました。私はこのような特別な「コンセプト」を発明することがエレガントであるかどうかはわかりません(抽象的ではない記憶を含む概念であると想像してください)。
一方、実際には、をこのコンセプト/要件を純粋な構文要件に翻訳して、後方に歩いてみましょう。私たちが標準に制限されている場合、連続性を保証する(またはほぼ保証する)クラスは何ですか?関連性の順に:すべてのこれらの
std::vector<T>
T[N] // !!
std::array<T, N>
std::string
std::initializer_list<T>
std::valarray<T>
、std::vector
、std::array
、std::string
は.data()
と呼ばれるメンバ関数を持っています。したがって、これで十分であれば、メンバー.data() -> T*
の存在を利用して連続したメモリを示すことができます。
1)型が連続していない場合は、構文エラーを発生させるためにメンバ関数.data()
を使用する努力を行います
2つのオプションがあります。 (たとえば、t[0]
を*t.data()
に置き換えた場合は難しくありません)
2).data()
にある種のSFINAEを使用してください。
template<class ContiguousSequence, typename = decltype(std::declval<ContigiousSequence>().data())>
void fun(ContiguousSequence&& s){...} // this function will only work with contiguous data
また、C++ 17は、.data()
との全てのタイプにそれを一般化し、さらにT[N]
とstd::initializer_list<T>
ためオーバーロードstd::data
を有しています。 ....data()
を上記のstd::data(...)
に置き換えることができます。
結論は、私はそれが良い慣例であると思い、その型は、値型連続する 要素へのポインタを返す(C++ 11または.data()
)data
機能を有している場合。
(あなたがstd::data(std::valarray<T>&)
に過負荷をかけない限り、[OK]を、std::valarray<T>
について?それは、何が動作しません。しかし、いずれにせよstd::valarray
を使用しています?それはC++のかなり放棄したコーナーで、私は思う)。最後
、のためのノートたとえば、明らかにstd::map
以下で明らかにstd::deque
には.data()
(またはstd::data(...)
)機能がありません。 boost::multi_array<..., N>
は.data()
のメンバーを持ち、配列要素へのポインタを返します。順序が明白ではないため、連続した配列であるかどうかは不明ですが、ある意味では連続したメモリの割り当てでもあります。
EDIT: 2つの現在、この問題に対処する提案(しかし、イテレータのレベルで)http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3884.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4284.html
'std :: array';) – Zeta
私が知る限り、そのような概念はありません。 std :: vector'、 'std :: string'と' std :: array'は '[0、c]の' i'に対して 'c.data()+ i ==&c [i]' 。サイズ()) '。 – Xeo
@ Xeo:そうです。概念はなく、要素(または 'char_type's)が*「連続して格納されている」という要件だけです*。 – Zeta