If there is any statement you would get rid of in C++ waht would it be?

Pages: 12
Just wondering if you could get rid of any statement what would it be, or if you could add any statement what would it be? I would probably add a statement that would write the program for me. :D
I'd add concepts :^(
I'd add a statement for the easy adding of other statements, and then add concepts and properties.

-Albatross
closed account (1yR4jE8b)
+1 Bazzy

I was extremely dissapointed when concepts were removed from the new standard.

I'd remove goto.
Last edited on
I'd remove goto.


But even goto has it's uses...

If I could guarantee compilers would implement it, I'd (re-)add export.
If I could guarantee compilers would implement it, I'd (re-)add export.


I support the above totally.
closed account (EzwRko23)
export - useless, non-portable
struct - redundant because of class
register - useless
inline - useless
friend - antipattern


If I could guarantee compilers would implement it, I'd (re-)add export.


There is no point in implementing export because it doesn't give you any benefit.
That is why C++0x deprecates it.

Anyway, removing keywords or features won't fix C++.
Better take a look at D. D is what C++ should have been.



Last edited on
using

I'd reply to xor* if I didn't know where it will end.
I'd definitely get rid of using and also the system() function.
I wouldn't remove a thing. There's a lot of code out there...
gets()
gets() is a good one.
friend - antipattern


No.

I'd reply to xor* if I didn't know where it will end.


I'll leave it at that then.
I'd like to see using go, but it does make a lot of code so much less verbose, especially if you're referencing something multiple layers deep in a namespace. Main point: I'd like to see textbooks stop saying that everyone should put "using namespace std;" in every file - stops them thinking about what they're doing half the time. And std:: doesn't really take up much space.

I've never had any cause to use friend, but I don't see it doing any harm really. gets() isn't well named, have seen it lead to confusion among new students. So that going would be good with me...

Though, really, any changes to C++ just means a hell of a headache for bringing currest work up to the new standard, which is fairly uninteresting work.
friend - antipattern


No.


I thought that was a rather absurd claim as well... but I didn't want to say anything.
If you remove using, you break the language. People forget that using has other purposes than "using namespace blah;".

For example, if I write my own generic sort function the correct way:

1
2
3
4
5
6
7
8
9
template< typename Iter, typename Compare >
void my_sort( Iter first, Iter last, Compare comp )
{
    using std::swap;    // This is absolutely necessary...
    // ...
    if( comp( *elem1, *elem2 ) )
        swap( *elem1, *elem2 );  // ... because this is the right way to write this line
   // ...
};


Why is this correct? Because this way, if the type referenced by *Iter is a user-defined
type and user has implemented their own swap() function for it, the above will call it.
If instead I wrote "std::swap( *elem1, *elem2 );" then it will not be called unless they
defined their swap() method in the std namespace, which they should not. (Correct
would be to define it in the same namespace as their type).



And, if you remove "friend", you make lines like:

 
MyMatrixType doubled = 2 * myMatrixInstance;


horribly inefficient since I now have to convert the scalar 2 to some matrix and
perform some kind of matrix multiplication (or else force me to write "myMatrixInstance * 2"
instead). Obviously friendship is needed to declare the appropriate function.


Actually I find myself never requiring to make my operators friends. Usually they can do whatever they need to do through the public interface.

Case in point... such an operator probably should be written like this:

1
2
3
4
inline MyMatrixType operator * (double a,const MyMatrixType& b)
{
  return b*a;
}


No friendship necessary. Calling the other * operator means no duplicate code.



Although where friendship is extremely useful is where you have tight-knit classes. It's not always wise to have one class to encompass everything, but you don't want to have to expose a lot of your internals to the public interface, either. friendship is the necessary middleground between two poor extremes.

I have a good example of this in something I did recently, but I'm running out of time, so I'll try and edit this post to include it when I get home.


EDIT:

So in a recent project of mine (for a game), I have two classes:

- Map (which represents the game map, where walls are, etc)
- MotionRect (which represents an object moving through the map. Something that needs to hit walls, etc)

The zinger is, I want to have some coarse exclusion when I do collision detection. So instead of checking every wall every time, I can take the MotionRect's position and use it to only check nearby walls.

Without friendship, the only way I could make this work would be to publicly expose either MotionRect's or Map's internals. Basically I'd have two options to choose from:

- MotionRect would need to see all of the walls in Map so it could pick out nearby walls. This blows a giant hole in Map's encapsulation. (bad option)

or

- Map would need to be aware of MotionRect and its members and do all the collision checking internally. This destroys MotionRect's encapsulation and forces MotionRect to be a dependency of Map... when Map really should not know anything about MotionRect (even worse option)


Fortunately, with friendship I can easily create a Map::Block class that acts as a "subsection" of the map. It alone can be exposed to Map's internals, preserving Map's encapsulation, while still serving as a separate entity.
Last edited on
jsmith: Couldn't you accomplish the same (only with more flexibility) by passing the swap function through a template parameter or a function pointer set to std::swap by default?
Using using to make decisions on which function to call seems rather messy, IMO. Suppose you're declaring your custom swap in the middle of a source, for some reason. The sort has different semantics depending on where on that file you call it, and the compiler will not give you any indication to that fact:
1
2
3
4
5
6
7
8
9
10
11
12
13
my_sort(begin,end); //Accepted, but possible subtle bug
//...
void swap(T &,T &);
//...
my_sort(begin,end); //Accepted

/* vs. */

my_sort(begin,end,my_swap); //Rejected
//...
void my_swap(T &,T &);
//...
my_sort(begin,end,my_swap); //Accepted 
I believe if Java can do away with friend concept in C++, it means friend is not mandatory at least in most OOP applications isn't it ? We can use Java interfaces concept instead.
You could, but if the function's purpose is to swap two elements, why not just call it swap (one name, one meaning)?

But passing via function pointer penalizes the user since the optimizer will not be able to inline
the function calls, so I would avoid passing by pointer.

Anyways, I would write my sort method to use swap() since that is most in line with std::sort().
(And std::sort needs to do what I wrote above, unless the STL writers specifically did not want
you to be able to customize swap() for your type, but that would be contrary to the whole idea
of specialization, which in this case can allow for optimization at least).

Besides, you have the same problem with your example with std::sort(). It's a problem with
template specialization in general. How can you be sure that the compiler invokes your
specialization vs. the default templated version?

You can't, unfortunately. I've run into this problem myself several times, particularly when
I'm writing static_visitors for boost::variants. In many cases, I can simply write a single
templated version of operator() because I do the same thing for all types. But then I add
another type later that needs to work differently. The compiler doesn't catch the fact that
I didn't write the specialization, and the code compiles cleanly; it just doesn't work.
Pages: 12