Call class method without parentheses in c++ - c++

Some c++ STL containers provide getters like
Foo.first
Foo.second
which apart from being very practical, improve code readability. Now suppose that I want to reproduce that feature in one of my own classes. Is it possible to define methods like
Matrix.components
Matrix.size
instead of
Matrix.components()
Matrix.size()
(same but without parentheses)? How could it be achieved?

No, because this is how you access public member variable in C++.
The container you refer to must be an std::pair and that's its public member variables (the two elements of the pair) that are accessed this way, i.e. data and not functions.
For your matrix, either make these member variables (but that's a bad idea regarding encapsulation), or leave them as functions (like many container in the standard lib do).

The .first and .second members are data, not code. Thus it doesn't make sense to "call" them. You methods aren't data, they're code, so you'd have to call them using (). Note that .size() is a method on all STL containers, never a data member.

Related

Why C++20 filter_view has a .size member function?

I found this on cppreference:
Following types are derived from std::ranges::view_interface and do
not declare their own size member function, but they cannot use the
default implementation, because their iterator and sentinel types
never satisfy sized_sentinel_for:
std::ranges::basic_istream_view
std::ranges::filter_view
std::ranges::join_view
std::ranges::split_view
std::ranges::take_while_view
This makes sense since those views can not calculate size in O(1). But I do not understand why then not make more than one base class for views, for example something like view_interface but without size member?
I presume that one possible reason is that ranges are already a insanely complicated library, but maybe I am missing something else.
If you wonder why this is a problem: maybe it is not, but I think/feel it is confusing to users since those views have member function that never works.
note: I know I can use distance, this is a question about design.
A class template is not a class. std::ranges::view_interface is not the base class of anything.
std::ranges::view_interface<std::ranges::filter_view<V, Pred>> does not have a size member. Other instantiations of std::ranges::view_interface do, but it's always been possible for one instantiation of a template to have members that another doesn't have.
The documentation for std::ranges::view_interface does mention that size is only present if (among other things) its sentinel and iterator type satisfy std::sized_sentinel_for.
I much prefer having one name that calculates appropriate capabilities, than a multitude of different names for subtly different capabilities. It is more extensible, if additional members are defined in later standards, everything automatically gains the members that it supports, without having to change e.g. sized_forward_view_interface to foobar_sized_forward_view_interface.

Member function vs friend functions: why one and not the other?

Why are functions of objects generally defined as class member functions instead of friend functions (with the associated instantiated object passed in as a parameter)?
If you implement push_back(vector v, val), front(vector v), back(vector) as friend functions that take as a parameter a vector, for example, would that not save on space, because the functions would not have to be defined each time a vector object is created, but only once?
I'm sorry if my question doesn't make much sense. I'm new to coding and I am not completely comfortable with its jargon/terminology. If I need to reword my question because it is unclear, please let me know.
Thank you :)
Unless they’re virtual, member functions don’t take up any space inside a class. And virtual member functions only take up constant space. This is usually 8 bytes, independent of how many virtual functions the class has. This is because classes with virtual functions contain a pointer to a vtable which looks up the actual function at runtime.
That being said, having friend functions at namespace scope is useful because it allows you to make overload sets. An overload set is just the name for all the overloads of a particular function name. For example, std::to_string is an overload set because there are multiple functions with that name.
Overload sets are a really useful concept because they allow you to write generic code that can act on a lot of different types, even if those types are completely unrelated For example, std::vector and std::list don’t inherit from each other or from a base class, but it’s easy to write templated functions that work on either of them because they share a common interface in terms of how they can be used.
If you implement push_back(vector v, val), front(vector v), back(vector) as friend functions that take as a parameter a vector, for example, would that not save on space, because the functions would not have to be defined each time a vector object is created, but only once?
Functions are not "defined each time a vector object is created". You don't save space by using friend functions as such.
The advantages of member functions mostly revolve around inheritance. Member functions can have protected access, and they can be virtual etc.
Friend functions are useful in implementing symmetric binary (i.e. two-argument, counting this) functions. As a member function the first argument would be special and cannot be treated equally. Furthermore, friend functions can provide an API compatible with C, which is useful for cross-language programming and shared libraries.

In C++, When Should I Make A Method Constant?

My question title pretty much asks it all. I've recently found out that it is good programming practice in C++ to pass many values by const reference and mark certain methods in classes as a constant method. Right now, I have a library that I have been writing for myself for a while now that has absolutely no const-correctness, so I'd like to start rectifying that little by little.
In what specific scenarios should I make a method constant? So far I know "getter" methods should generally be made constant (since the code in one shouldn't modify any class variables), but do I do that for all methods that are considered getters, or only specific ones? And outside of getter methods, what other scenarios should methods be made constant?
but do I do that for all methods that are considered getters, or only specific ones?
You should do that for all methods that don't modify the non-mutable members. They include not only getter functions but also any overloaded operator functions, such as operator==, operator!=, operator<.
When should I make a method constant?
As a rule of the thumb, you should make a method constant whenever none of the object's member variables are altered.
As an additional guideline, you should do this only when you are sure the method will not be altered in the future to change member variables.
Ultimately, if you are planning to make a method affect member variables, it should be non-constant. Otherwise, it should be constant.

Tagged container - is mimicking the container's interface a good practice?

Assume I have a container type to which I would like to attach additional information. My approach would be to define a class holding the container and the info. Is it good practice to define methods for the new class which mimic the container's methods? E.g., instead of writing myContainerObject.internalVector[i] I would like to write myContainerObject[i]. One would have to redefine every method one wishes to use (size(), push_back() etc.). What are the drawbacks of such an approach? What alternatives exist (e.g., is inheriting from a container the better solution?).
You are using composition with forwarding functions, and it's the right thing to do with concrete classes like STL containers. One drawback is that you have to redefine every overload of every function you want to allow, only to forward arguments, as well as parrot-typedef nested types (like iterator).
An alternative is to inherit but never publicly, only with private inheritance (because STL containers' destructor is public and non-virtual), then use using-declarations inside the custom class to bring names of base-class functions and types into scope (needing only one using Base::name; for all overloads of a function).
Possible ways of grasping a type which is a container, that I can think of:
Provide the a decorator (this is what you are asking about) whose component will be the internal container. This is can work when you have strict interfaces which you must comply with. It's neither good or bad practice. Read about decorator design pattern.
Use an iterator concept in your algorithms instead of a container. This a generic approach, and how stl algorithms are implemented
Use a container concept - similar to (2). Detect if the type is a container (SFINAE trick) and manipulate it.
Reimplement the container interface. You need a really strong reason to do it since it requires a significant amount of work/know-how. Some info: http://stdcxx.apache.org/doc/stdlibug/16-3.html
Generally , unless your uses case is very, very trivial or you have some specific requirements you should not expose class internal state (myContainerObject.internalVector[i]) to out side world.
Best practice is to keep the internals private and implement the [] operator and other functions (size() and such).

Is it always evil to have a struct with methods?

I've just been browsing and spotted the following...
When should you use a class vs a struct in C++?
The consensus there is that, by convention, you should only use struct for POD, no methods, etc.
I've always felt that some types were naturally structs rather than classes, yet could still have a few helper functions as members. The struct should still be POD by most of the usual rules - in particular it must be safe to copy using memcpy. It must have all member data public. But it still makes sense to me to have helper functions as members. I wouldn't even necessarily object to a private method, though I don't recall ever doing this myself. And although it breaks the normal POD rules, I wouldn't object to a struct having constructors, provided they were just initialise-a-few-fields constructors (overriding assignment or destructors would definitely be against the rules).
To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction. The logical place to put the helper functions for your collection-of-fields may well be within the struct.
I even think I once read some advice along these lines, though I don't remember where.
Is this against accepted best practice?
EDIT - POD (Plain Old Data) is misrepresented by this question. In particular, a struct can be non-POD purely because a member is non-POD - e.g. an aggregate with a member of type std::string. That aggregate must not be copied with memcpy. In case of confusion, see here.
For what it's worth, all the standard STL functors are defined as structs, and their sole purpose is to have member functions; STL functors aren't supposed to have state.
EDIT: Personally, I use struct whenever a class has all public members. It matters little, so long as one is consistent.
As far as the language is concerned, it doesn't matter, except for default private vs. public access. The choice is subjective.
I'd personally say use struct for PODs, but remember that "POD" doesn't mean "no member functions". It means no virtual functions, constructors, destructor, or operator=.
Edit: I also use structs for simple public-access aggregates of data, even if their members aren't PODs.
I tend to use struct a lot.
For the "traditional" OOP classes (the ones that represent a specific "thing"), I tend to use class simply because it's a common convention.
But most of my classes aren't really OOP objects. They tend to be functors, and traits classes and all sorts of other more abstract code concepts, things I use to express myself, rather than modelling specific "things". And those I usually make struct. It saves me having to type the initial public:, and so it makes the class definition shorter and easier to get an overview of.
I also lean towards making larger, more complex classes class. Except this rarely affects anything, because I lean even more towards refactoring large, complex classes... And then I'm left with small simple ones, which might be made struct's.
But in either case, I'd never consider it "evil". "Evil" is when you do something that actively obfuscates your code, or when you make something far more complex than necessary.
But every C++ programmer knows that struct and class mean virtually the same thing. You're not going to be confused for long because you see a struct Animal {...}; You know that it's a class designed to model an animal. So no, it's not "evil" no matter which way you do it.
When I have control over the style guides, everything is defined as a struct. Historically, I wanted all my objects to be one or the other, since I was taught it was undefined behavior to forward declared a struct as a class, and vice versa (I'm not sure if this was ever actually true, its just what I was told). And really, struct has the more reasonable default state.
I still do the same because I've never been convinced of the value of using it as a form of documentation. If you need to convey that an object only has public members, or doesn't have any member functions, or whatever arbitrary line you chose to draw between the two, you have actual documentation available for that. Since you never actually use the struct or class keyword when using the type, you would need to go hunting for the definition anyhow if you want the information. And with everybody having their own opinion on what struct actually means, its usefulness as self-documentation is reduced. So I shoot for consistency: everything as one or the other. In this case, struct.
Its not a popular way of doing things, to say the least. Fortunately for everybody involved, I very rarely have control over the coding standards.
I use a struct whenever I need an aggregate of public data members (as opposed to class, which I use for types that come with a certain level of abstractions and have their data private).
Whether or not such a data aggregate has member functions doesn't matter to me. In fact, I rarely ever write a struct without also providing at least one constructor for it.
You said, "To me a struct is intuitively a collection of fields - a data structure node or whatever". What you are describing is Plain Old Data. The C++ standard does have an opinion of what POD means with respect to C++ language features. I suggest that, where possible, you adopt the meaning of POD used in C++0x.
I need to find a reference for this, but I thought that, as far as type definitions are concerned, the keywords "struct" and "class" are to be synonyms in C++0x. The only difference being that class defaults to private members, while a struct defaults to public. This means that you'll never see complier error messages like "Type X first seen using struct, now seen using class." once we're all using C++0x.
I think that it is wrong to have strict rules on when to use class and when to use struct. If consistency is important to you, the go ahead and make a coding standard that has what ever sort of rules you like. Just make sure everyone knows that your coding standard relates to how you want you code to look - it doesn't relate to the underlying language features at all.
Maybe to give an example where I break all your rules, you say "To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction." When I want to write a class that implements some abstraction, I define the interface as a struct with pure virtual methods (egad!) - this is exposed in a header, as too is a factory method to construct my concrete class. The concrete class is not exposed i a public header at all. Since the concrete class is a secret, it can be implemented however I like and it makes no difference to external code.
I'd suggest that if you think that the keywords struct and class have any relation to the concept of POD, then you're not understanding C++ yet.