While designing a class or a function, which way, that is shown below, is better and why?
class Container {
//Provide this functionality??
void addItemVariadic(const Value& val, ...);
//Or provide this functionality??
void addItemList(const list<Value>& vals);
};
Is it better to provide a function like addItemVariadic(..), or addItemList(..)?
Or is it better to provide a set of such functions, like further taking some iterators, or is it better to limit the functionality, like just taking a list?
Using variadic functions is dangerous
If you ever pass a variable which has not the appriopriate type, it will crash at run time, when calling the function.
On the contrary if you use a std::list, it won't compile simply, and you avoid a crash.
Btw: I advice you to use std::vector instead of std::list in this case.
Edit1 Possible Dupplicate Question. with a nice solution using operator << to inputs all the parameters in one shot.
Edit2 So as to choose between different std::containers, there is a choose-graph as answer to this question. This graph addresses at C++03, it doesn't cover the new containers introduced in C++1.
Related
Anybody think there are advantages to using a class or struct to pass arguments ?
Like instead of
f(int,float,string)
Have
f(Args)
Where Args is struct with int,float,string members.
Advantage is easy to create multiple default parameters and not have to change function signature when new arguments added.
The obvious benefit would be to have logical grouping of semantically related data items.
Once you do, add some (member) operations on the structure that will guarantee your invariants.
The encapsulation raises the abstraction level of your code and this makes it easier to maintain/reason about.
See also Law Of Demeter
I think the great advantage is not having to rely to parameter order. Rely on order is error prone if you are changing frequently the interface, instead if you change the parameter struct you are always explicitly assigning values to a member variable which has a specific semantic.
Take for example Direct3D11 ID3D11Device::CreateDepthStencilState function: passing a const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDescis a lot more clear than asking for all the parameter it require.
Moreover think about modifiability: you don't need to change this method signature but only the underlying data structure during refactoring. I've found this especially useful when working collaboratively, where someone specify the interface and someone else have to implement it.
Anybody think there are advantages to using a class or struct to pass arguments ?
Yes, I think there's a lot of advantages.
Having large parameter lists on functions will distract client code from semantical parameter consistency, which can be better managed within an appropriate struct or class.
Also it's more flexible to use a struct, if additional (possibly optional) parameters need to be added later.
Whether you use one argument contained in a class/struct or multiple arguments depends on the meanings of the arguments.
Bad use of a struct:
struct Foo
{
char const* source;
char* destination;
};
Foo strcpy(Foo foo);
Good use of a struct:
struct Point
{
int x;
int y;
};
int distanceFromOrigin(Point p) { ... }
instead of
int distanceFromOrigin(int x, int y) { ... }
Doing the devil advocate here. There are also drawbacks here, mostly semantical. The first and foremost, it will require a lot of code if some of those args are passed by reference, another one by constant reference, the third one by const pointer and the forth by value. Would require you to explicitly write move constructor and default constructor for the argument struct, which will quickly become tedious. It would also be tedious to add members to that struct.
I also think using a struct is better: You can circumvent the hustle with parameter types and order. Suppose you have foo(A, B) (for types A and B). But still foo(b, a) might compile, depending on implicit constructions etc.
This concept can also be generalized using some kind of Context classes. Relying on C++11 variadic templates you could pass a "parameter superset context" to a subset one.
I have known that the function objects used in STL is just simple object that we can operator it like a function. That I can say the works of function and function objects is the same. If it's true, then why we should used function object rather than function?
The primary benefit is that calls to function objects (functors) are generally inlineable, where as calls to function pointers are generally not (prime example is comparing C's qsort to C++'s std::sort). For non-trivial objects/comparators, C++ should kill C's performance for sorting.
There are other benefits, for example you could possibly bind or store state in a functor, with which a raw function you cannot do.
Edit
Apologies for no direct reference, but Scott Meyers claims 670% improvement under certain circumstances:
Performance of qsort vs std::sort?
Edit 2
The passage with the performance note is this:
The fact that function pointer parameters inhibit inlining explains an
observation that long-time C programmers often find hard to believe:
C++’s sort virtually always embarrasses C’s qsort when it comes to
speed. Sure, C++ has function and class templates to instantiate and
funny-looking operator() functions to invoke while C makes a simple
function call, but all that C++ “overhead” is absorbed during
compilation. At runtime, sort makes inline calls to its comparison
function (assuming the comparison function has been declared inline
and its body is available during compilation) while qsort calls its
comparison function through a pointer. The end result is that sort
runs faster. In my tests on a vector of a million doubles, it ran up
to 670% faster, but don’t take my word for it, try it yourself. It’s
easy to verify that when comparing function objects and real functions
as algorithm parameters, there’s an abstraction bonus.
-Scott Meyers "Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library" - Item 46
The benefit of a function object over a function is that it can hold state (from wikipedia):
#include <iostream>
#include <iterator>
#include <algorithm>
class CountFrom {
private:
int &count;
public:
CountFrom(int &n) : count(n) {}
int operator()() { return count++; }
};
int main() {
int state(10);
std::generate_n(std::ostream_iterator<int>(std::cout, "\n"), 11, CountFrom(state));
return 0;
}
A regular function cannot hold state like a function object. If I remember correctly it was the way of getting around not having lambdas and closures (before C++11 wikipedia section)...
I think that the best thing about functors are that they can store information internally. Back in those days without std::bind, one would have to write lots of unary comparison functions so that it can be passed to certain routines like remove_if.
See http://cs.stmarys.ca/~porter/csc/ref/stl/function_objects.html.
STL uses function objects (functors) as a callback for sorting/searching containers.
Functors are templates and thus easier to implement as classes. Try saying greater<T> with a function pointer... considering that containers in STL are templates, too.
What are good use-cases for using tuples in C++11? For example, I have a function that defines a local struct as follows:
template<typename T, typename CmpF, typename LessF>
void mwquicksort(T *pT, int nitem, const int M, CmpF cmp, LessF less)
{
struct SI
{
int l, r, w;
SI() {}
SI(int _l, int _r, int _w) : l(_l), r(_r), w(_w) {}
} stack[40];
// etc
I was considering to replace the SI struct with an std::tuple<int,int,int>, which is a far shorter declaration with convenient constructors and operators already predefined, but with the following disadvantages:
Tuple elements are hidden in obscure, implementation-defined structs. Even though Visual studio interprets and shows their contents nicely, I still can't put conditional breakpoints that depend on value of tuple elements.
Accessing individual tuple fields (get<0>(some_tuple)) is far more verbose than accessing struct elements (s.l).
Accessing fields by name is far more informative (and shorter!) than by numeric index.
The last two points are somewhat addressed by the tie function. Given these disadvantages, what would be a good use-case for tuples?
UPDATE Turns out that VS2010 SP1 debugger cannot show the contents of the following array std::tuple<int, int, int> stack[40], but it works fine when it's coded with a struct. So the decision is basically a no-brainer: if you'll ever have to inspect its values, use a struct [esp. important with debuggers like GDB].
It is an easy way to return multiple values from a function;
std::tuple<int,int> fun();
The result values can be used elegantly as follows:
int a;
int b;
std::tie(a,b)=fun();
Well, imho, the most important part is generic code. Writing generic code that works on all kinds of structs is a lot harder than writing generics that work on tuples. For example, the std::tie function you mentioned yourself would be very nearly impossible to make for structs.
this allows you to do things like this:
Store function parameters for delayed execution (e.g. this question )
Return multiple parameters without cumbersome (un)packing with std::tie
Combine (not equal-typed) data sets (e.g. from parallel execution), it can be done as simply as std::tuple_cat.
The thing is, it does not stop with these uses, people can expand on this list and write generic functionality based on tuples that is much harder to do with structs. Who knows, maybe tomorrow someone finds a brilliant use for serialization purposes.
I think most use for tuples comes from std::tie:
bool MyStruct::operator<(MyStruct const &o) const
{
return std::tie(a, b, c) < std::tie(o.a, o.b, o.c);
}
Along with many other examples in the answers here. I find this example to be the most commonly useful, however, as it saves a lot of effort from how it used to be in C++03.
I think there is NO good use for tuples outside of implementation details of some generic library feature.
The (possible) saving in typing do not offset the losses in self-documenting properties of the resulting code.
Substituting tuples for structs that just takes away a meaningful name for a field, replacing the field name with a "number" (just like the ill-conceived concept of an std::pair).
Returning multiple values using tuples is much less self-documenting then the alternatives -- returning named types or using named references. Without this self-documenting, it is easy to confuse the order of the returned values, if they are mutually convertible.
Have you ever used std::pair? Many of the places you'd use std::tuple are similar, but not restricted to exactly two values.
The disadvantages you list for tuples also apply to std::pair, sometimes you want a more expressive type with better names for its members than first and second, but sometimes you don't need that. The same applies to tuples.
The real use cases are situations where you have unnameable elements- variadic templates and lambda functions. In both situations you can have unnamed elements with unknown types and thus the only way to store them is a struct with unnamed elements: std::tuple. In every other situation you have a known # of name-able elements with known types and can thus use an ordinary struct, which is the superior answer 99% of the time.
For example, you should NOT use std::tuple to have "multiple returns" from ordinary functions or templates w/ a fixed number of generic inputs. Use a real structure for that. A real object is FAR more "generic" than the std::tuple cookie-cutter, because you can give a real object literally any interface. It will also give you much more type safety and flexibility in public libraries.
Just compare these 2 class member functions:
std::tuple<double, double, double> GetLocation() const; // x, y, z
GeoCoordinate GetLocation() const;
With a real 'geo coordinate' object I can provide an operator bool() that returns false if the parent object had no location. Via its APIs users could get the x,y,z locations. But here's the big thing- if I decide to make GeoCoordinate 4D by adding a time field in 6 months, current users's code won't break. I cannot do that with the std::tuple version.
Interoperation with other programming languages that use tuples, and returning multiple values without having the caller have to understand any extra types. Those are the first two that come to my mind.
I cannot comment on mirk's answer, so I'll have to give a separate answer:
I think tuples were added to the standard also to allow for functional style programming. As an example, while code like
void my_func(const MyClass& input, MyClass& output1, MyClass& output2, MyClass& output3)
{
// whatever
}
is ubiquitous in traditional C++, because it is the only way to have multiple objects returned by a function, this is an abomination for functional programming. Now you may write
tuple<MyClass, MyClass, MyClass> my_func(const MyClass& input)
{
// whatever
return tuple<MyClass, MyClass, MyClass>(output1, output2, output3);
}
Thus having the chance to avoid side effects and mutability, to allow for pipelining, and, at the same time, to preserve the semantic strength of your function.
F.21: To return multiple "out" values, prefer returning a struct or tuple.
Prefer using a named struct where there are semantics to the returned value. Otherwise, a nameless tuple is useful in generic code.
For instance, if returned values are value from the input stream and the error code, these values will not ego far together. They are not related enough to justify a dedicated structure to hold both. Differently, x and y pair would rather have a structure like Point.
The source I reference is maintained by Bjarne Stroustrup, Herb Sutter so I think somewhat trustworthy.
What benefits has using std::reference_wrapper as template parameter of containers instead of raw pointers? That is std::vector<std::reference_wrapper<MyClass> > vs. std::vector<MyClass*>
I like forgetting about nulls and not having to use pointer syntax, but the verbosity of the types (i.e. vector<reference_wrapper<MyClass> >) plus having the call site use std::ref to wrap the actual reference makes me think it is not worth it.
I am referring to cases in which using std::shared_ptr or any other smart pointer is not an option.
Are there other benefits of using reference_wrapper or any other factors I am currently not taking into account? (I think my question applies to both C++11's reference_wrapper and boost's)
I don't think there is any technical difference. Reference wrapper provides basic pointer functionality, including the ability to change the target dynamically.
One benefit is that it demonstrates intent. It tells people who read the code that "whoever" has the variable, isn't actually controlling its lifespan. The user hasn't forgotten to delete or new anything, which some people may start to look for when they see pointer semantics.
C references are really problematic while working with templates. If you are "lucky" enough to compile code with reference as a template parameter you might have problems with code that would work (for some reason) as follows:
template<class T> f(T x) { g(x); }
template<class T> g(T x) { x++; }
Then even if you call f<int&>(x) it will call g<int>. But reference_wrapper works fine with templates.
As also mentioned earlier - you will have problems with compiling things like vector<int&>, but vector<reference_wrapper<int>> works fine.
I'm using C++ templates to pass in Strategy functors to change my function's behavior. It works fine. The functor I pass is a stateless class with no storage and it just overloads the () operator in the classic functor way.
template <typename Operation> int foo(int a)
{
int b=Operation()(a);
/* use b here, etc */
}
I do this often, and it works well, and often I'm making templates with 6 or 7 templated functors passed in!
However I worry both about code elegance and also efficiency. The functor is stateless so I assume the Operation() constructor is free and the evaluation of the functor is just as efficient as an inlined function, but like all C++ programmers I always have some nagging doubt.
My second question is whether I could use an alternate functor approach.. one that does not override the () operator, but does everything in the constructor as a side effect!
Something like:
struct Operation {
Operation(int a, int &b) { b=a*a; }
};
template <typename Operation> int foo(int a)
{
int b;
Operation(a,b);
/* use b here, etc */
}
I've never seen anyone use a constructor as the "work" of a functor, but it seems like it should work. Is there any advantage? Any disadvantage? I do like the removal of the strange doubled parenthesis "Operator()(a)" , but that's likely just aesthetic.
Any disadvantage?
Ctors do not return any useful value -- cannot be used in chained calls (e.g. foo(bar()).
They can throw.
Design point of view -- ctors are object creation functions, not really meant to be workhorses.
Compilers actually inline the empty constructor of Operation (at least gcc in similar situations does, except when you turned off optimization)
The disadvantage of doing everything in the constructor is that you cannot create a functor with some internal state this way - eg. functor for counting the number of elements satisfying a predicate. Also, using a method of a real object as a functor allows you to store the instance of it for later execution, something you cannot do with your constructor approach.
From a performance pov the code demonstrated with get completely optimized with both VC and GCC. However, a better strategy often is to take the functor as a parameter, that way you get a lot more flexibility and identical performance characteristics.
I'd recommend defining functor that work with the STL-containers, i.e. they should implement operator(). (Following the API of the language you're using is always a good idea.)
That allow your algorithms to be very generic (pass in functions, functors, stl-bind, boost::function, boost::bind, boost::lambda, ...) which is what one usually wants.
This way, you don't need to specify the functor type as a template parameter, just construct an instance and pass it in:
my_algorithm(foo, bar, MyOperation())
There does not seem any point in implementing the constructor in another class.
All you are doing is breaking encapsulation and setting up your class for abuse.
The constructor is supposed to initialize the object into a good state as defined by the class. You are allowing another object to initialize your class. What guarantees do you have that this template class knows how to initialize your class correctly? A user of your class can provide any object that could mess with the internal state of your object in ways not intended.
The class should be self contained and initialize itself to a good state. What you seem to be doing is playing with templates just to see what they can do.