If there's no invariant to be kept regarding some data, it should be public. Many people overdo their classes and add completely useless getter/setters, but you don't have to.
Getters and setters are not supposed to always link to underlying fields. They can do that, but this is not the general idea. The question is not why do you want to use function instead of direct access, because in abstract types the presence of addressable field is not at all suggested. There is a big difference between capsulated and open type.
The reason why you might have non-trivial accessors:
1. The location of the underlying item may not be in the structure of the class. A function can cloak the location, not only from the user of the type, but from the code-generation step of the build process for other modules. Where the item resides can be established when the function is called. This increases the flexibility, and also can be used to decrease the dependencies for compilation. Like in the pImpl idiom.
2. The value may be computed, not stored in its own addressable unit of memory. For example, a date object may have year, month, day, hour, second, millisecond. All those fields can be stored in a single integer, and extracted from it with computations. The accessor methods provide illusion for the existence of actual fields.
3. There may be side effects from the accessors. Setting new values may trigger events to interested subscribers. This is frequently used in GUI frameworks. The user or the program may alter the value of some property, and some pieces of code may need to be launched after the event. As another specific example, you may need to update the reference count of a pointer when you overwrite the value held in the smart pointer that manages it.
You can find counterexamples, when accessors are not technically necessary, but with capsulated types you really have no choice. Also, getters and setters are not the only approach for doing this, and you might need incremental operations. Reading and writing does not always suffice.
Regards
EDIT: In other words, I defend the view that you should use accessors, because they are part of your interface. You don't create classes in order to partition some solution in pieces. This is how companies usually think, but I don't share this view. You create them in order to separate the implementation from the abstract specification of their responsibilities. Virtually no one does that in practice.
Making a type entirely open, such as pair, is not a problem. The hybrid policy (part closed, part open) is IMO mostly perversion. I also do not like generalizations, but I will sweat hard to find example where having some fields public and some private is the most graceful solution.
EDIT: May be if the base class is encapsulated and the derived class is a plain structure that inherits its supporting functions, or some setup like that. It's hard to stretch the imagination.
The only semantic difference between a struct and a class is that a struct-s access modifier defaults to public and a class-es access modifier defaults to private.
I will sweat hard to find example where having some fields public and some private is the most graceful solution.
Me too, but I wouldn't say such a situation will never occur.
You should never generalize (that's a generalization as well btw) - std::pair for example.
But to generalize;) it: When a class is completely inactive (does nothing with it's members) i.e. is just meant for the transport of data then getters/setters are just tedious.
At the moment a class becomes active (does something with it's data members) I agree that it's far to dangerous to access the data members of that class directly. Especially in a multi threading environment.
The above example makes sense in order to make 'a' read only.