- 浏览: 497799 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
hypercube:
markin'
配置D语言编程环境 -
qiezi:
qiezi 写道yangyang_08 写道1 ...
我的编程语言学习经历 -
qiezi:
yangyang_08 写道1、现在如果做并发服务器,楼主选用 ...
我的编程语言学习经历 -
yangyang_08:
1、现在如果做并发服务器,楼主选用什么样的语言架构?2、lua ...
我的编程语言学习经历 -
dearplain:
我也是语言爱好者,不过我一直坚持使用c。
我的编程语言学习经历
文档从MSDN抄过来的,稍稍改了一下。
范型算法是一个算法适应无数种容器,所有 STL 容器的迭代器都支持提领,所以一个 find 算法就能应用于所有容器包括内置数组身上,但是D没有提领就不行
上面的这个 find 函数被你改了,呵呵
好主意,可以实现成这样:
代码
1. iter = 3; // 等价于C++的:*iter = 3;
2. int i = iter(); // 等价于C++的:int i = *iter;
返回引用然后操作引用对象就不需要了,毕竟是C++专有的。
这样我个人感觉语意上有点问题,而且 iter() 的形式也不能让范型算法支持指针所表示的数组。
比如:
由于内置的数组是一个相当于 vector 的实现,但是却没有迭代器,因此感觉语言内部和外部的容器接口有点问题
双向链表的迭代迭代器是双向迭代器,不支持大小比较,而且也不支持 += 2。
链表中的节点在堆中的位置完全是随机的,后加入的节点的地址不一定比老节点大。
STL 是数据结构和算法实现的典范,值得好好学习。
module array; struct random_access_iterator(T) { private: alias random_access_iterator!(T) self_type; T[] array; size_t pos; public: static self_type opCall(T[] array, size_t pos) { self_type ret; ret.array = array; ret.pos = pos; return ret; } T[] get_array() { return array; } size_t get_pos() { return pos; } T opCall() { return array[pos]; } void opAssign(T value) { array[pos] = value; } void check_array(T[] array) { if (array !is this.array) throw new Exception("not same array object"); if (this.pos > array.length) throw new Exception("invalid iterator"); } self_type opAdd(int delta) { return self_type(this.array, this.pos + delta); } self_type opAdd_r(int delta) { return opAdd(delta); } self_type opPostInc() { return opAddAssign(1); } self_type opAddAssign(int delta) { this.pos += delta; if (this.pos > this.array.length) this.pos = this.array.length; return *this; } self_type opSub(int delta) { return self_type(this.array, this.pos - delta); } self_type opSub_r(int delta) { return opSub(delta); } self_type opPostSub() { return opSubAssign(1); } self_type opSubAssign(int delta) { this.pos -= delta; if (this.pos > this.array.length) this.pos = this.array.length; return *this; } self_type opNeg() { int pos = (-this.pos) % this.array.length; return self_type(this.array, pos); } T opCast() { return this.array[this.pos]; } int opCmp(self_type rhs) { if (this.array != rhs.array) throw new Exception("can't compare iterators of different array"); return cast(int)this.pos - cast(int)rhs.pos; } int opEquals(self_type rhs) { if (this.array == rhs.array && this.pos == rhs.pos) return 1; return 0; } } template iterator(T : T[]) { alias random_access_iterator!(T) iterator; } /****************************************************************************** * Returns an element at a specified location in the array. * * Returns: * A value to the element subscripted in the argument. * If pos is greater than the size of the array, at throws an exception. * * Params: * array = Array object. * pos = The subscript or position number of the element to reference * in the array. * * Example: * -------------------------------------- * // array_at.d * voud main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 20 ); * * int i = v1.at( 0 ); * int j = v1.at( 1 ); * dout << "The first element is " << i << endl; * dout << "The second element is " << j << endl; * } * -------------------------------------- * * Output: * The first element is 10<br /> * The second element is 20 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ T at(T)(inout T[] array, int pos) { return array[pos]; } unittest { printf("test array.at\n\0"); int[] array = [1,2,3]; assert(array.at(0) == 1); assert(array.at(1) == 2); assert(array.at(2) == 3); assert(array == [1,2,3]); } /****************************************************************************** * Returns last element of the array. * * Returns: * The last element of the array. If the array is empty, the return * value is undefined. * * Params: * array = Array object. * * Remarks: * When compiling with _SECURE_SCL 1, a runtime error will occur if * you attempt to access an element in an empty array. See Checked * Iterators for more information. * * Example: * ------------------------------------- * // array_back.d * void main() { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 11 ); * * int i = v1.back( ); * * dout << "The last integer of v1 is " << i << endl; * } * ------------------------------------ * * Output: * The last integer of v1 is 11 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * front and back *****************************************************************************/ T back(T)(inout T[] array) { version(_SECURE_SCL) { return array[$-1]; } else { T result; if (!array.empty()) result = array[$-1]; return result; } } unittest { printf("test array.back\n\0"); int[] array = [1,2,3]; int b = array.back(); assert(b == 3); assert(array == [1,2,3]); } /****************************************************************************** * Returns the number of elements that the array could contain without * allocating more storage. * * Returns: The current length of storage allocated for the array. * * Params: * array = Array object. * * Remarks: The member function resize will be more efficient if sufficient * memory is allocated to accommodate it. Use the member function * reserve to specify the amount of memory allocated. <br /> * This function is <b>deprecated</b>. * * Example: * ------------------------------------ * // array_capacity.d * * void main( ) * { * int[] v1; * * for (int i=0; i<16; ++i) * v1.push_back( 1 ); * dout << "The length of storage allocated is " * << v1.capacity( ) << "." << endl; * * v1.push_back( 2 ); * dout << "The length of storage allocated is now " * << v1.capacity( ) << "." << endl; * } * ------------------------------------ * * Output: * The length of storage allocated is 16.<br /> * The length of storage allocated is now 32. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * array.size and array.capacity ******************************************************************************/ // deprecated size_t capacity(T)(inout T[] array) { if (array.length <= 16) return 16; for (size_t i=32; true; i *= 2) { if (i > array.length) return i; if (i > (1 << 30)) return size_t.max; } return size_t.max; } unittest { printf("test array.capacity\n\0"); int[] array = []; assert(array.capacity() == 16); int[] array1 = [1]; assert(array1.capacity() == 16); int[] array2 = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; assert(array2.capacity() == 16); int[] array3 = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16,17]; assert(array3.capacity() == 32); } /****************************************************************************** * Erases the elements of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_clear.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * dout << "The size of v1 is " << v1.size( ) << endl; * v1.clear( ); * dout << "The size of v1 after clearing is " << v1.size( ) << endl; * } * ------------------------------------ * * Output: * The size of v1 is 3<br /> * The size of v1 after clearing is 0 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ ******************************************************************************/ void clear(T)(inout T[] array) { array.length = 0; } unittest { printf("test array.clear\n\0"); int[] array = [1,2,3]; array.clear(); assert(array.length == 0); } /****************************************************************************** * Tests if the array is empty. * * Returns: * true if the array is empty; false if the array is not empty. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_empty.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * * if ( v1.empty( ) ) * dout << "The array is empty." << endl; * else * dout << "The array is not empty." << endl; * } * ------------------------------------ * Output: * The array is not empty. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ bool empty(T)(inout T[] array) { return 0 == array.length; } unittest { printf("test array.empty\n\0"); int[] array = [1,2,3]; assert(array.empty() == false); int[] array1 = []; assert(array1.empty() == true); } /****************************************************************************** * Returns a random-access iterator to the first element in the container. * * Returns: A random-access iterator addressing the first element in the array * or to the location succeeding an empty array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_begin.d * * void main( ) * { * int[] c1; * iterator!(int[]) c1_Iter; * * c1.push_back( 1 ); * c1.push_back( 2 ); * * c1_Iter = c1.begin( ); * dout << "The first element of c1 is "<< *c1_Iter << endl; * * c1_Iter = 20; * c1_Iter = c1.begin( ); * dout << "The first element of c1 is now "<< c1_Iter << endl; * } * ------------------------------------ * * Output: * The first element of c1 is 1<br > * The first element of c1 is now 20 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * array.empty, array.erase, and array.push_back *****************************************************************************/ iterator!(T[]) begin(T)(inout T[] array) { return iterator!(T[])(array, 0); } unittest { printf("test array.begin\n\0"); int[] array = [1,2,3]; auto begin = array.begin(); assert(begin == iterator!(int[])(array, 0)); } /****************************************************************************** * Returns a random-access iterator that points just beyond the end of the * array. * * Returns: * random-access iterator to the end of the array object. If the array * is empty, array.end == array.begin. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_end.d * * void main( ) * { * int[] v1; * iterator!(int[]) v1_Iter; * * v1.push_back( 1 ); * v1.push_back( 2 ); * * for ( v1_Iter = v1.begin( ) ; v1_Iter != v1.end( ) ; v1_Iter++ ) * cout << v1_Iter.get << endl; * } * ------------------------------------ * * Output: * 1<br /> * 2 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ iterator!(T[]) end(T)(inout T[] array) { return iterator!(T[])(array, array.length); } unittest { printf("test array.end\n\0"); int[] array = [1,2,3]; auto end = array.end(); assert(end == iterator!(int[])(array, 3)); } /****************************************************************************** * Removes an element in a array from specified position. * * Returns: * An iterator that designates the first element remaining beyond any * elements removed, or a pointer to the end of the array if no such * element exists. * * Params: * array = Array object. * where = Position of the element to be removed from the array. * * Example: * ------------------------------------ * // array_erase.d * * void main( ) * { * int[] v1; * iterator!(int[]) Iter; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * v1.push_back( 40 ); * v1.push_back( 50 ); * * dout << "v1 =" ; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * * v1.erase( v1.begin( ) ); * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * } * ------------------------------------ * * Output: * v1 = 10 20 30 40 50<br /> * v1 = 20 30 40 50 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * empty, erase, and push_back *****************************************************************************/ iterator!(T[]) erase(T)(inout T[] array, iterator!(T[]) where) { where.check_array(array); for (int i=where.get_pos(); i<array.length-1; ++i) array[i] = array[i+1]; array.length = array.length - 1; return iterator!(T[])(array, where.get_pos()); } unittest { printf("test array.erase\n\0"); int[] array = [1,2,3]; iterator!(int[]) begin = array.begin(); // DMD does not support this: // array.erase(array, begin); erase!(int)(array, begin); assert(array == [2,3]); } // 以下部分必须注释掉,DMD不允许这种重载,应该是个BUG /****************************************************************************** * Removes a range of elements in a array from specified positions. * * Returns: * An iterator that designates the first element remaining beyond any * elements removed, or a pointer to the end of the array if no such * element exists. * * Params: * array = Array object. * first = Position of the first element removed from the array. * last = Position just beyond the last element removed from the * array. * * Example: * ------------------------------------ * // array_erase.d * * void main( ) * { * int[] v1; * iterator!(int[]) Iter; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * v1.push_back( 40 ); * v1.push_back( 50 ); * * dout << "v1 =" ; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * * v1.erase( v1.begin( ) ); * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * * v1.erase( v1.begin( ) + 1, v1.begin( ) + 3 ); * cout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * cout << " " << *Iter; * cout << endl; * } * ------------------------------------ * * Output: * v1 = 10 20 30 40 50<br /> * v1 = 20 30 40 50<br /> * v1 = 20 50 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * empty, erase, and push_back *****************************************************************************/ /* iterator!(T[]) erase(T)(inout T[] array, iterator!(T[]) first, iterator!(T[]) last) { return null; } */ /****************************************************************************** * Returns a reference to the first element in an array. * * Returns: * The first element in the array object. If the array is empty, the * return is undefined. * * Params: * array = Array object. * * Remarks: * When compiling with _SECURE_SCL 1, a runtime error will occur if you * attempt to access an element in an empty array. See Checked * Iterators for more information. * * Example: * ------------------------------------ * // array_front.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 11 ); * * int i = v1.front( ); * * cout << "The first integer of v1 is "<< i << endl; * } * ------------------------------------ * * Output: * The first integer of v1 is 10 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * front and back *****************************************************************************/ T front(T)(inout T[] array) { version(_SECURE_SCL) { return array[0]; } else { if (!array.empty()) return array[0]; T result; return result; } } unittest { printf("test array.front\n\0"); int[] array = [1,2,3]; int f = array.front(); assert(f == 1); assert(array == [1,2,3]); } /****************************************************************************** * Inserts an element or a number of elements or a range of elements into the * array at a specified position. * * Returns: * The first insert function returns an iterator that points to the * position where the new element was inserted into the array. * * Params: * array = Array object. * where = The position in the array where the first element is * inserted. * value = The value of the element being inserted into the array. * * Remarks: * Any insertion operation can be expensive, see vector Class for a * discussion of array performance. * * Example: * ------------------------------------ * // array_insert.cpp * * int main( ) * { * int[] v1; * iterator!(int[]) Iter; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * dout << "v1 =" ; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * * v1.insert( v1.begin( ) + 1, 40 ); * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * v1.insert( v1.begin( ) + 2, 4, 50 ); * * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * * v1.insert( v1.begin( )+1, v1.begin( )+2, v1.begin( )+4 ); * dout << "v1 ="; * for (Iter = v1.begin( ); Iter != v1.end( ); Iter++ ) * dout << " " << Iter.get(); * dout << endl; * } * ------------------------------------ * * Output: * v1 = 10 20 30<br /> * v1 = 10 40 20 30<br /> * v1 = 10 40 50 50 50 50 20 30<br /> * v1 = 10 50 50 40 50 50 50 50 20 30 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ iterator!(T[]) insert(T)(inout T[] array, iterator!(T[]) where, T value) { where.check_array(array); array.length = array.length + 1; for(int i=array.length-1; i>where.get_pos(); i--) array[i] = array[i-1]; array[where.get_pos()] = value; return iterator!(T[])(array, where.get_pos()); } unittest { printf("test array.insert\n\0"); int[] array = [1,2,3]; auto begin = array.begin(); insert!(int)(array, begin, 4); assert(array == [4,1,2,3]); } /****************************************************************************** * Deletes the element at the end of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_pop_back.cpp * * int main( ) * { * int[] v1; * * v1.push_back( 1 ); * dout << v1.back( ) << endl; * v1.push_back( 2 ); * dout << v1.back( ) << endl; * v1.pop_back( ); * dout << v1.back( ) << endl; * } * * Output: * 1<br/> * 2<br/> * 1 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * See_Also: * push_back and pop_back *****************************************************************************/ void pop_back(T)(inout T[] array) { if (array.length) array.length = array.length - 1; } unittest { printf("test array.pop_back\n\0"); int[] array = [1,2,3]; array.pop_back(); assert(array.length == 2); assert(array == [1,2]); array.pop_back(); assert(array.length == 1); assert(array == [1]); array.pop_back(); assert(array.length == 0); array.pop_back(); assert(array.length == 0); } /****************************************************************************** * Adds an element to the end of the array. * * Params: * array = Array object. * value = The element added to the end of the array. * * Example: * ------------------------------------ * // array_push_back.cpp * * void main( ) * { * int[] v1; * * v1.push_back( 1 ); * if ( v1.size( ) != 0 ) * dout << "Last element: " << v1.back( ) << endl; * * v1.push_back( 2 ); * if ( v1.size( ) != 0 ) * dout << "New last element: " << v1.back( ) << endl; * } * ------------------------------------ * * Output: * Last element: 1<br/> * New last element: 2 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * push_back and pop_back<br /> * accumulate, copy, and push_back<br /> * adjacent_difference and push_back<br /> * empty, erase, and push_back *****************************************************************************/ void push_back(T)(inout T[] array, T value) { array ~= value; } unittest { printf("test array.push_back\n\0"); int[] array = [1,2,3]; array.push_back(4); assert(array == [1,2,3,4]); array.push_back(5); assert(array == [1,2,3,4,5]); } /****************************************************************************** * Specifies a new size for a array. * * Params: * array = Array object. * newsize = The new size of the array. * value = The value of new elements added to the array if the new size * is larger that the original size. If the value is omitted, * the new objects are assigned the default value. * * Remarks: * If the container's size is less than the requested size, _newsize, * elements are added to the array until it reaches the requested size. * If the container's size is larger than the requested size, the * elements closest to the end of the container are deleted until the * container reaches the size _newsize. If the present size of the * container is the same as the requested size, no action is taken. * * size reflects the current size of the array. * * Example: * ------------------------------------ * // array_resize.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * v1.resize( 4,40 ); * cout << "The size of v1 is " << v1.size( ) << endl; * cout << "The value of the last object is " << v1.back( ) << endl; * * v1.resize( 5 ); * cout << "The size of v1 is now " << v1.size( ) << endl; * cout << "The value of the last object is now " << v1.back( ) << endl; * } * ------------------------------------ * * Output: * The size of v1 is 4<br /> * The value of the last object is 40<br /> * The size of v1 is now 5<br /> * The value of the last object is now 0 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void resize(T)(inout T[] array, size_t newsize, T value = T.init) { array.length = newsize; } unittest { printf("test array.resize\n\0"); int[] array = [1,2,3]; array.resize(cast(uint)5); assert(array == [1,2,3,0,0]); array.resize(cast(uint)2); assert(array == [1,2]); } /****************************************************************************** * Reserves a minimum length of storage for a array object, allocating space if * necessary. * * Params: * array = Array object. * count = The minimum length of storage to be allocated for the array. * * Example: * ------------------------------------ * // array_reserve.cpp * * void main( ) * { * int[] v1; * * v1.reserve( 20 ); * } * ------------------------------------ * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void reverse(T)(inout T[] array, size_t count) { size_t oldlen = array.length; array.length = count; array.length = oldlen; } unittest { printf("test array.reverse can't test\n\0"); } /****************************************************************************** * Returns the number of elements in the array. * * Returns: * The current length of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_size.d * * voud main( ) * { * int[] v1; * size_t i; * * v1.push_back( 1 ); * i = v1.size( ); * dout << "Vector length is " << i << "." << endl; * * v1.push_back( 2 ); * i = v1.size( ); * dout << "Vector length is now " << i << "." << endl; * } * ------------------------------------ * * Output: * Vector length is 1.<br /> * Vector length is now 2. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * size and capacity *****************************************************************************/ size_t size(T)(inout T[] array) { return array.length; } unittest { printf("test array.size\n\0"); int[] array = [1,2,3]; assert(array.size() == 3); int[] array1 = [1,2]; assert(array1.size() == 2); } /****************************************************************************** * Exchanges the elements of two arrays. * * Params: * array = Array object. * right = A array providing the elements to be swapped, or a array * whose elements are to be exchanged with those of the array * _left. * left = A array whose elements are to be exchanged with those of the * array _right. * * Example: * ------------------------------------ * // array_swap.d * void main( ) * { * int[] v1, v2; * * v1.push_back( 1 ); * v1.push_back( 2 ); * v1.push_back( 3 ); * * v2.push_back( 10 ); * v2.push_back( 20 ); * * dout << "The number of elements in v1 = " << v1.size( ) << endl; * dout << "The number of elements in v2 = " << v2.size( ) << endl; * dout << endl; * * v1.swap( v2 ); * * dout << "The number of elements in v1 = " << v1.size( ) << endl; * dout << "The number of elements in v2 = " << v2.size( ) << endl; * } * ------------------------------------ * * Output: * The number of elements in v1 = 3<br /> * The number of elements in v2 = 2<br /> * * The number of elements in v1 = 2<br /> * The number of elements in v2 = 3<br /> * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void swap(T)(inout T[] left, inout T[] right) { T[] temp = left; left = right; right = temp; } unittest { printf("test array.swap\n\0"); int[] array1 = [1,2,3,4]; int[] array2 = [4,3,2,1]; array1.swap(array2); assert(array1 == [4,3,2,1]); assert(array2 == [1,2,3,4]); } import std.stdio; void main() { int[] a = [1,2,3]; assert(a.at(0) == 1); auto i = a.begin(); auto b = a.end(); while(i != a.end()) { printf("%d\n\0", i()); i ++; } auto iter = a.begin(); writefln(iter()); iter = 5; writefln(a); }
评论
50 楼
oldrev
2007-04-07
感觉 opAssign 用来设置值语意上有问题,比如:
List!(int).Iterator i1, i2;
i1 = i2; // 设置迭代器本身的值
i1 = 100; // 设置i1指向的值为100
一个类型两种赋值语意?
List!(int).Iterator i1, i2;
i1 = i2; // 设置迭代器本身的值
i1 = 100; // 设置i1指向的值为100
一个类型两种赋值语意?
49 楼
oldrev
2007-04-07
遗憾的是数组的外部“成员函数”不能省略(),要不就更统一了
48 楼
oldrev
2007-04-07
我的已经修改为 opAssign 和 opCall了,
这下我们各自的容器应该可以互动了
这下我们各自的容器应该可以互动了
47 楼
qiezi
2007-04-07
支持内置类型我倒不觉得应该像C++学习,我这里的数组也是类置类型,不过加上“Array Operations”,已经不需要find再去支持指针类型了,所以提领是完全可以避免的。
就算是一个指针,也可以利用D的数组把它转过来:
这时arr.ptr和p是指向同一位置的,不会产生内存拷贝,所以修改arr的内容也会到p指向的内存。
就算是一个指针,也可以利用D的数组把它转过来:
int* p = ...; 指向某缓冲区 int[] arr = p[0..3];
这时arr.ptr和p是指向同一位置的,不会产生内存拷贝,所以修改arr的内容也会到p指向的内存。
46 楼
qiezi
2007-04-07
STL迭代器使用提领也是一种约定,D不支持它,也可以约定另一种嘛,可以用opCall,也可以加个get方法,只要都使用它就行了,没必要因为语法上不支持就吊死了。。
上面这个修改就是为了支持我现在的代码。。
上面这个修改就是为了支持我现在的代码。。
45 楼
oldrev
2007-04-07
引用
这个完全没有问题亚:
代码
1. iterator find(iterator, T)(iterator first, iterator last, T value)
2. {
3. auto i = first;
4. while(i != last && i() != value) i++;
5. return i;
6. }
7.
8. import std.stdio;
9. void main()
10. {
11. int[] arr = [1,2,3];
12. writefln("array: ", arr);
13.
14. auto r = find(arr.begin(), arr.end(), 2);
15. writefln("pos: ", r.get_pos());
16.
17. erase!(int)(arr, r);
18. writefln("array: ", arr);
19. }
输出:
[5,2,3]
array: [1,2,3]
pos: 1
array: [1,3]
还有其它例子证明这个有问题吗?
代码
1. iterator find(iterator, T)(iterator first, iterator last, T value)
2. {
3. auto i = first;
4. while(i != last && i() != value) i++;
5. return i;
6. }
7.
8. import std.stdio;
9. void main()
10. {
11. int[] arr = [1,2,3];
12. writefln("array: ", arr);
13.
14. auto r = find(arr.begin(), arr.end(), 2);
15. writefln("pos: ", r.get_pos());
16.
17. erase!(int)(arr, r);
18. writefln("array: ", arr);
19. }
输出:
[5,2,3]
array: [1,2,3]
pos: 1
array: [1,3]
还有其它例子证明这个有问题吗?
范型算法是一个算法适应无数种容器,所有 STL 容器的迭代器都支持提领,所以一个 find 算法就能应用于所有容器包括内置数组身上,但是D没有提领就不行
上面的这个 find 函数被你改了,呵呵
44 楼
qiezi
2007-04-07
前面的迭代器+2问题已经解决了。
43 楼
qiezi
2007-04-07
上面输出第1行是另一段的,多拷了一行。。
42 楼
qiezi
2007-04-07
这个完全没有问题亚:
输出:
[5,2,3]
array: [1,2,3]
pos: 1
array: [1,3]
还有其它例子证明这个有问题吗?
iterator find(iterator, T)(iterator first, iterator last, T value) { auto i = first; while(i != last && i() != value) i++; return i; } import std.stdio; void main() { int[] arr = [1,2,3]; writefln("array: ", arr); auto r = find(arr.begin(), arr.end(), 2); writefln("pos: ", r.get_pos()); erase!(int)(arr, r); writefln("array: ", arr); }
输出:
[5,2,3]
array: [1,2,3]
pos: 1
array: [1,3]
还有其它例子证明这个有问题吗?
41 楼
oldrev
2007-04-07
我的实现更新了
40 楼
oldrev
2007-04-07
引用
好主意,可以实现成这样:
代码
1. iter = 3; // 等价于C++的:*iter = 3;
2. int i = iter(); // 等价于C++的:int i = *iter;
返回引用然后操作引用对象就不需要了,毕竟是C++专有的。
这样我个人感觉语意上有点问题,而且 iter() 的形式也不能让范型算法支持指针所表示的数组。
比如:
private IterType find(IterType, ValueType)(IterType first, IterType last, ValueType val) { IterType i = first; while(i != last && *i != val) ++i; return i; }
由于内置的数组是一个相当于 vector 的实现,但是却没有迭代器,因此感觉语言内部和外部的容器接口有点问题
39 楼
qiezi
2007-04-07
我修改到代码里了,现在可以这样:
auto iter = a.begin(); writefln(iter()); iter = 5;
38 楼
qiezi
2007-04-07
好主意,可以实现成这样:
返回引用然后操作引用对象就不需要了,毕竟是C++专有的。
iter = 3; // 等价于C++的:*iter = 3; int i = iter(); // 等价于C++的:int i = *iter;
返回引用然后操作引用对象就不需要了,毕竟是C++专有的。
37 楼
oldrev
2007-04-07
必须用到函数签名这就是问题所在了,不一定所有人都同意叫get/set,除非在语言标准里定下来。
好像实现重载提领与现在的语言并不冲突呀
或者实现为 opCall?
好像实现重载提领与现在的语言并不冲突呀
或者实现为 opCall?
36 楼
qiezi
2007-04-07
指针在D里面是应该避免使用的,尽量用于底层代码。
C++的方式:
D里面可以改成set/get方法:
风格更统一一些。
C++的方式:
iter = vec.begin(); *iter = 3; int a = *iter; int& b = *iter; b = 5;
D里面可以改成set/get方法:
iter = array.begin(); iter.set(3); int a = iter.get(); iter.set(5);
风格更统一一些。
35 楼
oldrev
2007-04-07
D实现iterator有个问题是D不支持重载指针提领,很难实现STL风格的iterator。而且与 C++ 不同的是指针和数组是两种类型,真是麻烦。
34 楼
oldrev
2007-04-07
我的双向链表模板类:
http://oldrev.iteye.com/admin/show/68748
http://oldrev.iteye.com/admin/show/68748
33 楼
oldrev
2007-04-07
我现在正在写个双向链表类,等一下我贴出来玩玩
32 楼
oldrev
2007-04-07
那要是v1_Iter+=2把end跳过了怎么办? 标准是人定的,错误也是人犯的。 链表的iterator也是可以比较大小的,就看怎么实现了。
双向链表的迭代迭代器是双向迭代器,不支持大小比较,而且也不支持 += 2。
链表中的节点在堆中的位置完全是随机的,后加入的节点的地址不一定比老节点大。
STL 是数据结构和算法实现的典范,值得好好学习。
31 楼
qiezi
2007-04-07
通常+=2也最多只会到end,所以不会跳过。我的实现没有考虑到这个,有时间还得改改。
发表评论
-
D语言模板和编译期执行
2012-07-29 00:15 0D语言模板继承了C++模板的基本用法,在其上做了相当多扩充,近 ... -
Generator
2008-04-09 13:46 2009几种并发编程模型开销(从大到小): Process > ... -
lambda之路...
2007-11-09 22:57 2867DMD最近的版本号加入了闭包,感觉非常有用,虽然有些背后动作, ... -
像Erlang一样写D程序
2007-09-15 10:23 6732琢磨了好久,一直没时间来做它。在讨论这个问题的时候就已经有这想 ... -
[D语言] qsort的尴尬
2007-05-06 21:31 5080phobos里面在stc.c.stdlib里提供了qsort, ... -
强类型数值计算
2007-04-10 21:45 4722以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇 ... -
简单的单元测试框架
2007-04-10 21:20 3148做了个简单的单元测试框架,只算个毛坯,遇到一些问题。 1、由 ... -
编译期执行的效率
2007-03-15 15:58 4224写了一个编译期执行的fibonacci模板: templ ... -
D语言编译期生成和编译期执行技术
2007-02-24 14:35 4122借助D语言新的mixin表达式,可以完成一些代码生成功能,比如 ... -
如何获得一个方法的名字?
2007-01-15 19:24 3491在D语言中,一个方法你可以得到它的指针(函数指针或委托),但不 ... -
D语言的函数编程
2007-01-07 11:17 3858前阵子论坛上有人问我D语言做函数编程怎样,老实说我没怎么想过这 ... -
D语言和python的差异
2007-01-07 10:12 6555这2个语言的比较怪怪的,我最近转换了一些twisted的源文件 ... -
从简单测试看D数组内存分配策略
2007-01-07 09:43 3228D语言动态数组可以在运行期改变大小,这和C++的vector相 ... -
DMD 0.178发布
2006-12-24 15:32 4602What's New for D 0.178 ... -
GDC 0.20发布
2006-12-17 14:35 2799引用 * Updated to DMD 0.177 * Fix ... -
DMD 0.177发布
2006-12-09 18:47 2275没什么亮点,BUG修复得也不多,BUG数量始终保持在250-2 ... -
DMD 0.176发布
2006-12-03 14:22 3072引用 What's New for D 0.176 Dec ... -
D语言的成员函数模板
2006-12-02 20:29 3075DMD 0.166 特性列表中有一条: * ncorp ... -
D语言 在栈上分配对象 以及 无需GC拖管对象
2006-11-28 13:18 2811一、栈上分配对象 C++可以轻易实现在栈上和堆上分配对象,例 ... -
打算把twisted移植到D语言上
2006-11-26 20:14 4211twisted是一个优秀的python网络开发库,以前用它做过 ...
相关推荐
C++ STL(Standard Template Library,标准模板库)是C++编程语言中不可或缺的一部分,它提供了一组高效且灵活的算法、容器和迭代器。在STL中,`vector`是一种非常重要的容器,它是一个动态数组,允许在任意位置进行...
2. 成员函数:`std::array`提供了一系列的成员函数,如`size()`用于获取大小,`data()`返回原始数组的指针,以及重载的`[]`操作符用于访问元素。 3. 类型安全:由于`std::array`的大小是模板参数的一部分,所以在...
在这个例子中,`std::vector`作为STL的容器,替代了原始数组,`push_back`方法用于添加元素,而范围for循环则简化了求平均值的过程,无需手动管理索引。 总的来说,尽管STL的语法可能对初学者来说较为复杂,但它的...
STL,全称为Standard Template Library(标准模板库),是C++编程语言中的一部分,它提供了一组高效、灵活且可重用的容器、迭代器、算法和函数对象(仿函数)。STL的主要目标是提高代码的简洁性、可读性和性能。在...
例如,`vector`的插入和删除操作在大多数情况下比原始数组更快,因为它会自动处理内存管理和元素移动。 STL的文档详细介绍了每个组件的使用方法、接口以及注意事项,是学习和使用STL的重要参考资料。对于开发者来说...
STL的算法库包含了一组通用的函数模板,用于执行各种常见操作,如排序(`std::sort`)、查找(`std::find`)、复制(`std::copy`)、合并(`std::merge`)等。这些算法可以作用于任何容器,通过迭代器来访问元素,...
### 数组(一维、二维、三维)的动态申请及用vector的表示方法 #### 一、变长一维数组 变长数组是指在编译时不能确定数组长度,而是在程序运行时需要动态分配内存空间的数组。下面详细介绍如何在C++中实现变长一维...
STL,全称为Standard Template Library(标准模板库),是C++编程语言中的一部分,它提供了一组高效且灵活的数据结构和算法。STL的核心概念包括容器、迭代器、算法和函数对象,这些组件共同构成了一个强大的工具箱,...
C++ STL库是C++标准库的一个重要组成部分,它提供了丰富的数据结构和算法,极大地提升了C++编程的效率和灵活性。以下是对C++ STL库知识的详细总结。 首先,STL(Standard Template Library,标准模板库)包含了六大...
向量(Vector)是C++标准模板库(STL)中的一个动态数组容器。向量提供了比传统数组更高级的功能,如动态内存管理、大小的自动调整、成员访问和迭代器支持。声明向量时,需要包含头文件 `<vector>` 并指定存储的数据...
常见的容器有数组(`std::array`)、向量(`std::vector`)、列表(`std::list`)、链表(`std::forward_list`、`std::list`)、集合(`std::set`、`std::unordered_set`)、映射(`std::map`、`std::unordered_map`...
1. 容器:STL提供了多种类型的容器,如数组(array)、向量(vector)、列表(list)、链表(forward_list)、双链表(list)、集合(set)、映射(map)、无序集合(unordered_set)和无序映射(unordered_map)。...
- “swap技巧”是一种有效减少`std::vector`或`std::string`多余容量的方法。 - 这有助于提高程序的整体性能。 **描述:** - 通过交换两个容器的内部数据,可以有效地将一个容器的容量减小到其实际大小。 - 示例...
它提供了一组方法来操作这些元素,包括添加、删除、访问和修改。例如,我们可以使用`push_back()`方法向数组列表末尾添加元素,使用`pop_back()`方法移除最后一个元素,使用`size()`获取元素数量,以及通过索引访问...
3. **算法**:STL提供了一组广泛的算法,这些算法不依赖于特定的容器实现,可以对容器中的元素进行操作,如排序(sort)、查找(find)、拷贝(copy)、删除(remove)等。这些算法大大简化了复杂操作的编写,提高了...
STL,全称为Standard Template Library(标准模板库),是C++编程语言中不可或缺的一部分,它为程序员提供了高效且可重用的数据结构和算法。STL的核心理念是泛型编程,这意味着它能处理不同类型的对象,提高了代码的...
1. **容器**:容器是一组对象的集合,提供了对这些对象的管理方式。例如,`Array`(数组)、`Vector`(动态数组)、`List`(双链表)、`Set`(集合)和`Map`(映射)等。这些容器提供了丰富的操作接口,如插入、删除...
它提供了一组高效、可重用的容器、迭代器、算法和函数对象,极大地提高了C++程序员的开发效率。JavaScript,另一方面,是Web前端开发的主导语言,通常与HTML和CSS一起用于构建交互式的网页应用。尽管JavaScript自身...
题目给出了一组字符串的定义和比较操作: ```cpp char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char *str5 = "abc"; const char *str6 = "abc"; cout ...
而“STL编程指南”则专注于C++编程,STL是C++的一个重要组成部分,提供了一组高效的数据结构(如vector、list、set)和算法(如排序、查找),极大地提高了代码的可读性和效率。 在编程领域,掌握算法和数据结构是...