Didn’t say this is the best way, but this is how it’s done in 90% of shogun ;)
On Sat, 12 May 2018 at 15:46, Fernando J. Iglesias García < [email protected]> wrote: > When passing SGVector (or any non-primitive type) as an argument, I think > it is a good idea to use either const reference (for input or read-only > parameters) or pointer (for input and output parameters). In this way it is > clear from the calling site whether a method/function will modify its > arguments. > > A bit more on this: > https://google.github.io/styleguide/cppguide.html#Reference_Arguments > > On 12 May 2018 at 11:47, Heiko Strathmann <[email protected]> > wrote: > >> BTW if you see pointers to SGVectors being passed around, that should >> probably be changed. Can you share the locations of it? >> H >> >> 2018-05-12 10:46 GMT+01:00 Heiko Strathmann <[email protected]>: >> >>> Hi >>> >>> I cc the list as others might have the same question. >>> >>> SGVector (same for SGMarix) is a memory wrapper for c/c++ arrays, that >>> implements an automatic reference counter and therefore shared ownership. >>> If you assign the vector to another one using operator=, (or similarly, >>> pass it by value), then what happens is that a new SGVector structure is >>> generated, but it points to the same memory. Once all SGVector instances >>> that point to the memory block are destroyed, the memory block is freed. >>> This is why passing it by value is relatively efficient (it doesnt copy >>> the actual memory) and in particular it allows shared ownership, such as >>> SGVector<float64_t> get_vector() { return m_vector; } >>> which returns returns a copy of the SGVector instance that points to the >>> same memory that m_vector does. >>> This would allow me to modify a member variable as >>> auto vec = obj->get_vector() >>> vec[0] = 5; // now the memory block where Object::m_vector points to is >>> changed >>> >>> Now sometimes, helper methods that accept vectors are called many times >>> (in a loop). Copy- assigning the SGVector doesnt copy the memory block but >>> creates a new instance everytime, which can be slow. This is why we >>> sometimes pass around references, in particular const references make a >>> speed difference (see linalg). >>> There should never be the need to pass a pointer to an SGVector to a >>> helper method. >>> >>> Summary answer to your questions: >>> Passing SGVector by value creates a shared ownership of a fixed memory >>> block. >>> With respect to the memory block, passing SGVector by value allows for >>> what you called inplace updates (of the memory block). >>> Whenever you pass vectors to a helper method, you dont need to share >>> ownership, and therefore you can pass a by reference (if you want to >>> modify) or even const reference (if you just want to read). Obviously, >>> shared ownership comes at a (small) cost, which you might want to avoid in >>> low-level methods (say linalg). >>> >>> Hope that helps! >>> H >>> >>> >>> 2018-05-12 2:54 GMT+01:00 Elfarouk Harb <[email protected]>: >>> >>>> Hi Heiko, >>>> >>>> Just a quick question about something that is confusing me a bit. Some >>>> times, if there is a need to do an inplace update of a variable, I see that >>>> SGVector<T> is passed by a pointer, meaning: >>>> SGVector<T>* ref_vars. However, sometimes, they are passed to functions >>>> which do in place updates but they are passed by value: SGVector<T> >>>> ref_vars (example: >>>> http://shogun-toolbox.org/api/latest/DescendUpdaterWithCorrection_8cpp_source.html#l00054 >>>> variable_reference is passed by value but the function acts on it as if >>>> it is passed by reference). Is SGVector somehow being passed by >>>> reference in both ways or am I missing something? >>>> >>>> Thanks a lot, >>>> Elfarouk >>>> >>> >>> >> > -- Sent from my phone
