begin
end
私は、より一般的なアルゴリズムとデータ構造を自由に記述できるという新しい概念が本当に気に入っています。begin(range)
現在、呼び出しとbegin(*range)
、型がコレクションへの参照をポインターとして保持している場合とを区別する必要がある場合があります。独自のコレクション型のポインターに対して、begin/end のオーバーロードを常に提供することをお勧めします。
struct Container {
int values[3];
};
const int* begin(const Container& c);
const int* end(const Container& c);
const int* begin(const Container* c);
const int* end(const Container* c);
template<typename Range>
int Sum(const Range& range)
{
return std::accumulate(begin(range), end(range), 0);
}
int main(void)
{
Container c = {1, 2, 3};
std::cout << Sum(c);
std::cout << Sum(&c);
}
これが良いアイデアだった場合、これのテンプレートを提供してみませんか:
template<typename Range>
auto begin(const Range* r) -> decltype(begin(*r)){
using std::begin;
return begin(*r);
}
template<typename Range>
auto end(const Range* r) -> decltype(end(*r)) { /* ... */ }
int main(void)
{
Container c = {1, 2, 3};
std::vector<int> v = {1, 2, 3}
std::cout << Sum(c);
std::cout << Sum(&c);
std::cout << Sum(v);
std::cout << Sum(&v);
}
これが良いアイデアだった場合、なぜ標準ライブラリはそれを定義しないのでしょうか?
私の質問は:template<typename R>
auto begin(const R* r)
テンプレートに問題はありますか? これが何らかの理由で失敗するケースはありますか?