Stephan T. Lavavej - Core C++, 10 of n (Nov 2013 CTP)

Download this episode

Download Video

Download captions

Download Captions

Description

In part 10, STL explores the new features in the Visual C++ Compiler November 2013 CTP (Community Technology Preview), in addition to the features that were added between VC 2013 Preview and RTM.

Features included in the November CTP ( generic lambdas!!! Smiley ):

C++11, C++14, and C++/CX features:

  • Implicit move special member function generation (thus also completing =default)
  • Reference qualifiers on member functions (a.k.a. "& and && for *this")
  • Thread-safe function local static initialization (a.k.a. "magic statics")
  • Inheriting constructors
  • alignof/alignas
  • __func__
  • Extended sizeof
  • constexpr (except for member functions)
  • noexcept (unconditional)
  • C++14 decltype(auto)
  • C++14 auto function return type deduction
  • C++14 generic lambdas (with explicit lambda capture list)
  • (Proposed for C++17) Resumable functions and await

 

See part 1: Name Lookup
See part 2: Template Argument Deduction
See part 3: Overload Resolution
See part 4: Virtual Functions
See part 5: Explicit and Partial Specialization
See part 6: New C++11 features added to the Visual C++ 2012 compiler (CTP)
See part 7: Usual Arithmetic Conversions and Template Metaprogramming
See part 8: do-while loop, casts, one definition rule
See part 9: lambdas and other expressions

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • User profile image
      NotFredSafe

      Printing the 101 inside test2() is kind of redundant, because if zeroth didn't return a reference, the expression ++zeroth(v) would not even compile, right?

    • User profile image
      Matt_PD

      Wow, thanks! Smiley

      After looking at the features, I'm guessing this may be as good place to ask as any:

      - how viable is running VC 2012 Ultimate, VC 2013 Pro RTM, and VC Nov 2013 CTP (all three) alongside each other?

      - any precautions I should take?
      -- any risk they'd be stepping over each other's settings, in particular "Microsoft.Cpp.Win32.user.props"/"Microsoft.Cpp.x64.user.props" (here: used for system-wide binary-libs deployment (and configuration -- paths, etc.); I suppose that even if so, there's still a chance of alleviating any potential problems via compiler-version-specific paths using macros?)?
      -- any chance of reusing Boost Binaries built for MSVC 2013 in MSVC Nov 2013 CTP (if binary compatibility isn't expected, as I vaguely seem to recall, any experience with building Boost in MSVC Nov 2013 CTP? :>)

      On another thought, sorry if this is too specific to ask here -- admittedly, I'm hoping for STL answering (guessing experimenting with multiple recent MSVC versions is not particularly wild in this context) ;>

    • User profile image
      Simon Buchan

      I've hit a use nearly half of these features while quickly trying out 2013 RTM, so I'm really interested to give this a try soon!

      You mentioned constexpr has restrictions in this release (better than it ICEing!) - are those defined anywhere yet?

      Generic lambdas are nice, I guess, but they're pretty wordy compared to other lambda syntaxes still, it would be cool to see something like [](a, b) { a += b; } in C++17 (default to auto&&). Stroustrop's Concepts-lite paper at one point (doesn't look lite it's in there anymore?) contained a neat shorthand for templates that looks like a nice solution for the decltype(t) problem mentioned: instead of:

      template <typename T, typename U> auto inner(T&& t, const U& u) { ... }

      and

      [](auto&& t, const auto& u) { inner(forward<decltype(t)>(t)); }

      you could type (something like):

      typename{T,U} auto inner(T&& t, U&& u) { ... }

      and

      []typename{T,U}(T&& t, const U& u) { inner(forward<T>(t)); }

      though typename was supposed to be a Concept name for that. For some reason, it doesn't look like it's in the current version of the paper, though I might just be missing it.

    • User profile image
      STL

      NotFredSafe> Printing the 101 inside test2() is kind of redundant, because if zeroth didn't return a reference, the expression ++zeroth(v) would not even compile, right?

      Yes for integers, no in general. Given int yinsh(), ++yinsh() is ill-formed (N3797 5.3.2 [expr.pre.incr]/1, "The operand shall be a modifiable lvalue.", and the expression yinsh() is a prvalue). However, given UDT zertz(), ++zertz() will be well-formed if the UDT overloads op++(). (For example, deque<T>::iterator.) This is because the preincrement is fancy syntax for a member function call, and non-const member functions can be called on temporaries (prvalues) unless specifically forbidden with ref-qualifiers (which didn't exist in C++98/03).

      Mostly though, I considered it more fun to print something than to say "look, it compiles!".

      Matt_PD> how viable is running VC 2012 Ultimate, VC 2013 Pro RTM, and VC Nov 2013 CTP (all three) alongside each other?

      Running 2012 RTM/Update N and 2013 RTM side-by-side is supported and extensively tested. (As usual, there may be bugs in obscure corner cases.) The Nov 2013 CTP requires 2013 RTM, and *should* be unaffected by 2012's presence.

      > -- any chance of reusing Boost Binaries built for MSVC 2013 in MSVC Nov 2013 CTP

      Because this is compiler-only, you can probably get away with mixing-and-matching. I wouldn't recommend it, though.

      > (if binary compatibility isn't expected, as I vaguely seem to recall, any experience with building Boost in MSVC Nov 2013 CTP? :>)

      I believe the compiler front-end test team has been building Boost, but I don't know the details of their work.

      Simon Buchan> You mentioned constexpr has restrictions in this release (better than it ICEing!) - are those defined anywhere yet?

      It's not available on (non-static) member functions, including constructors. (I confirmed this with the compiler dev who implemented it.)

    • User profile image
      Charles

      I just have to yell...  STL!!!!

      Another awesome installment. Thank you, man. Such a treat to have you do your thing on camera, on C9. That's rock and roll, all around.
      C

    • User profile image
      froglegs

       In the video you mentioned that constexpr supports for loops, but when I tried to use one

       

      constexpr auto Give(int blah){ for (int i = 0; i < 5; ++i) { blah = blah * 2; }return blah; }

      It errored out on me, with this message:

      error C3249: illegal statement or sub-expression for 'constexpr' function
      warning C4649: '++': operator results in a non-constant expression

       

      Is this supposed to work in C++14, or does it just not work because the CTP is incomplete?

    • User profile image
      STL

      I forgot to ask whether we had implemented C++11 or C++14 constexpr for the CTP, much less what our plans for the next RTM are.  (Before filming my video, I dropped by all of the compiler devs' offices and interrogated them about their features, hence the detailed caveats I presented - I should have remembered about constexpr's spec changing but I didn't.)  I'll find out.

    • User profile image
      Isaac Lascasas

      Great video and great job, I have been using 2013 for a while now and I'm very happy. It is allways nice to see c++ moving. Still waiting for concept support here hehe.

    • User profile image
      Matt_PD

      STL: Great, thanks for your reply (and for continuing Core C++ installments)!

    • User profile image
      AFacchi

      Awesome lecture! Is incredible the amount of things I learn every time I watch your series. Very interesting, as always.

      And also, congratulations to the MSVC team for implementing all this new features! 

    • User profile image
      Sebastian Redl

      The non-await version of the code at the end is full of errors! Missing return (in the "next" lamdba), incorrect recursive call of the "next" lambda, and I don't think the "next" lamdba is captured correctly either.

      Which just demonstrates the point, but still.

    • User profile image
      STL

      Thanks for watching, everyone!

      I've confirmed that the CTP is targeting C++11 constexpr (minus member functions), not C++14's extended rules which will require more infrastructure work in the compiler. They're working on it, but we can't promise anything for the next RTM.

      Sebastian Redl> The non-await version of the code at the end is full of errors!

      Yeah, that was just a quick sketch that Deon sent to me. I was all, "I'm filming in an hour, can you give me anything for await?"

    • User profile image
      Kostas Dritsas

      Great lecture!

    • User profile image
      MFH

      Great, like always!

       

    • User profile image
      chrisaverage

      As always - great stuff STL!

      One question about auto return type. Is it possible to indicate somehow that you want to return a reference? Something like auto& func() {... or do you just use return std::move(...) and it knows?

    • User profile image
      STL

      You would say decltype(auto) for the return type, then return an lvalue (like ptr[idx]) for X&, or an xvalue (like move(ptr[idx])) for X&&.

    • User profile image
      chrisaverage

      ah, I watched again and you talked about it. sorry, somehow I missed that bit. thx.

    • User profile image
      Ben Hanson

      Regarding constexpr, I notice that non-member constexpr functions dealing with strings don't work:

      template<std::size_t N>
      constexpr std::size_t valid_helper(const char (&sql)[N], const std::size_t num_params, std::size_t i,
      std::size_t acc = 0)
      {
      return sql[i] >= '0' && sql[i] <= '9' ?
      valid_helper(sql, num_params, i + 1, acc * 10 + sql[i] - '0') :
      sql[i] == '}' ?
      acc < num_params ?
      i :
      ~0 :
      i;
      }

      template<std::size_t N>
      constexpr std::size_t valid(const char (&sql)[N], const std::size_t num_params, std::size_t i)
      {
      return sql[i] >= '0' && sql[i] <= '9' ?
      valid_helper(sql, num_params, i) :
      ~0;
      }

      template<std::size_t N>
      constexpr std::size_t next(const char (&sql)[N], const std::size_t num_params, std::size_t i = 0)
      {
      return i > N ? ~0 :
      sql[i] == 0 ? i :
      sql[i] == '{' ?
      next(sql, num_params, valid(sql, num_params, i + 1)) :
      next(sql, num_params, i + 1);
      }

      int main(int argc, char *argv[])
      {
      static_assert(next("SELECT {2}, {1}", 2) != ~0, "Out of bounds");
      return 0;
      }

    • User profile image
      STL

      Thanks, I'll ask the compiler dev who wrote constexpr.  That's emitting "warning C4425: 'const char (&)[N]' : 'constexpr' was ignored (class literal types are not yet supported)" which at the very least is an inaccurate warning.

    • User profile image
      Ben Hanson

      > Thanks, I'll ask the compiler dev who wrote constexpr.

      Thanks Stephan.

    • User profile image
      STL

      I've gotten confirmation that constexpr arrays are also a CTP limitation, they just reused the warning for class literal types (which was confusing).

    • User profile image
      Spetum

      wow. Great.

      Thanks Stephan.

    • User profile image
      Dan Golick

      Do the reumable functions support generators as in the working paper.

      This will give us c# yield behavior. (Which makes linq possible etc...)

    • User profile image
      abir

      With Nov CTP for Visual Studio 2013, some template alias, which used to work with RTM version no longer works.
      1)
      template<bool B,class T1,class T2>
      using if_ = typename std::conditional<B, T1,T2>::type;
      template<unsigned N>
      using meow = if_<(N <= 8), char, int>;
      static_assert(std::is_same<meow<10>,int>::value,"error");
      It seems the alias truncates N to bool before placing it in if_

      2)
      template<bool B, class E = void>
      using enable_if = typename std::enable_if<B, E>::type;
      template<class T>
      enable_if<std::is_integral<T>::value, void> meow(T x){}
      template<class T>
      enable_if<std::is_floating_point<T>::value, void> meow(T x){}

      This complains that function meow already defined.

      3) somewhat different story to enable_if in class definition. That only causes problem, when it is inside another template.
      template<class T> //comment out this line to compile
      struct meow
      {
      template<class U,class E = void>
      struct purr;
      template<class U>
      struct purr < U, enable_if<std::is_integral<U>::value > > {};
      template<class U>
      struct purr < U, enable_if<std::is_floating_point<U>::value > > {};
      };

    • User profile image
      STL

      abir: Your #1 successfully compiles with our latest compiler build. (They've fixed several bugs in alias templates after the CTP snapshot was taken, most of which were found while we were implementing std::integer_sequence.)

      I've filed your #2 as DevDiv#835786 in our internal database, and your #3 as DevDiv#835794.

    • User profile image
      STL

      Dan Golick> Do the reumable functions support generators as in the working paper.

      I asked Deon, who implemented await, and he said: "Not in the current implementation. We're still working on the design for it."

    • User profile image
      fdwr

      (naming hindsight lament) Interesting watch. Thanks for summarizing (love the non-static member initialization). @7:38 "Standardization committee really hates introducing new keywords"

      Instead of using "using", I'd have preferred the standards committee introduce a new type name with "typename", or even define a new type with "typedef" where the presence of an "=" indicates the sane ordering (more like typical assignment instead of backwards like it is now). They are understandably allergic to inventing new keywords, but they could have at least chosen the more natural one rather than a present progressive verb.

      typedef CatPtr = Cat*; // instead of "using CatPtr = Cat*;"
      template<typename T> typedef Cat = Animal<T, Mammal>;

    • User profile image
      szx

      Why did they call it __func__ rather than __FUNC__?

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.