Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use C++0x Features Now?

Tags:

With the official release of VS 2010, is it safe for me to start using the partially-implemented C++0x feature set in my new code?

The features that are of interest to me right now are both implemented by VC++ 2010 and recent versions of GCC. These are the only two that I have to support.

In terms of the "safety" mentioned in the first sentence: can I start using these features (e.g., lambda functions) and still be guaranteed that my code will compile in 10 years on a compiler that properly conforms to C++0x when it is officially released?

I guess I'm asking if there is any chance that VC++ 2010 or GCC will end up like VC++ 6; it was released before the language was officially standardized and consequently allowed grossly ill-formed code to compile.

After all, Microsoft does say that "10 is the new 6". ;)

like image 474
svu2g Avatar asked Apr 14 '10 15:04

svu2g


People also ask

What is c 0x?

C++0x is the working draft of the new C++ programming language standard. Note: C++0x is a new version of the C++ programming language standard. IBM continues to develop and implement the features of the new standard. The implementation of the language level is based on IBM's interpretation of the standard.

What is STD C ++ 0x?

C++0x was the working name for the new standard for C++, adding many language features that I'll cover in this series on C++11. In September 2011, C++0x was officially published as the new C++11 standard, and many compilers now provide support for some of the core C++11 features.


2 Answers

There are several items I've already discovered that are not written to the standard. For instance, this would not work:

  struct test {   int operator()(int); };  std::cout << typeid( std::result_of<test(int)>::type ).name() << std::endl; 

According to the wikipedia site on C++0x it should. Apparently VS2010 uses the TR1 definition of result_of, which is different from what C++0x will have (based on decltype).

Also, this does not work:

  std::bind<int>([](int i)->int {return i; }); 

It fails because calling std::result_of (well, the implementation of it), fails because the lambda type has no result_of typedef. This is of course why you supply the return type to the bind call but apparently it ignores it for some reason and continues to search on its own. The boost version of bind works as expected. For this reason we're continuing to use the boost version of bind in our project.

Also, if you'll note on http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx?CommentPosted=true#commentmessage that there's some changes yet to be implemented by VS2010 that will effect lambda expressions. I haven't been able to break them but then I haven't used nested lambdas and probably never will.

You should also keep in mind that boost::shared_ptr and std::shared_ptr are incompatible. Not surprising, but you must know this if you intend to use one or the other...I'd recommend not both and we're just going to stick with boost.

There's also no declval in VS2010. Easy enough to make though:

 template < typename T > T&& declval(); 

Example of use:

 template < typename T > struct point {   T x,y; };  template < typename T1, typename T2 > point<decltype(declval<T1>() + declval<T2>())> operator + (point<T1> const& lh, point<T2> const& rh) {  ... } 

You'll also note in the page I linked above that I've already discussed with members of the dev team (or the PR part or whatever) that there's a bug in decltype. There's more than just the one I mention so I'll show both:

 template < typename T1, typename T2 > auto operator + (point<T1> const& lh, point<T2> const& rh)   -> point<decltype(lh.x + rh.x)> { ... } point<int> x; point<double> y; point<double> pt = x + y; // fails, operator + returned point<const double>  void f(); auto ptr = &f;  std::cout << typeid( decltype(*ptr) ).name() << std::endl; std::cout << typeid( decltype(*&f) ).name() << std::endl; // should output the same thing...outputs void (*)() 

Also...according to some email exchanges about decltype and result_of, this should work:

  std::result_of< decltype(f)() >::type x = f();  

With my home brewed version of std::result_of that uses decltype this would work if the decltype(f)() expression worked correctly. It does not. Gives some error about function returning a function. You have to use "decltype(&f)()" to make the expression work.

So, sure...we're using it. There's some bugs and crap though. The benefits outweigh waiting IMHO. Don't expect your code to be standard when the standard comes out though and future MS compilers may break it.

like image 70
Edward Strange Avatar answered Sep 20 '22 15:09

Edward Strange


The C++0X feature set is pretty fixed by now, so I'd say go for it. The final draft of the proposal should be done in august according to wikipedia.

A lot of the things are available from boost anyway (actually, a lot of 0X things come from boost) - see boost TR1. You can re-use those features through boost even if the compiler isn't fully C++0X.

like image 37
Joris Timmermans Avatar answered Sep 21 '22 15:09

Joris Timmermans