Effective Modern C++

Scott Meyers

Mentioned 11

Presents a collection of tips for programmers on how to use the features of C++11 and C++14 effectively, covering such topics as functions, rvalue references, and lambda expressions.

More on Amazon.com

Mentioned in questions and answers.

This question attempts to collect the few pearls among the dozens of bad C++ books that are published every year.

Unlike many other programming languages, which are often picked up on the go from tutorials found on the Internet, few are able to quickly pick up C++ without studying a well-written C++ book. It is way too big and complex for doing this. In fact, it is so big and complex, that there are very many very bad C++ books out there. And we are not talking about bad style, but things like sporting glaringly obvious factual errors and promoting abysmally bad programming styles.

Please edit the accepted answer to provide quality books and an approximate skill level — preferably after discussing your addition in the C++ chat room. (The regulars might mercilessly undo your work if they disagree with a recommendation.) Add a short blurb/description about each book that you have personally read/benefited from. Feel free to debate quality, headings, etc. Books that meet the criteria will be added to the list. Books that have reviews by the Association of C and C++ Users (ACCU) have links to the review.

Note: FAQs and other resources can be found in the C++ tag info and under . There is also a similar post for C: The Definitive C Book Guide and List


Introductory, no previous programming experience

  • Programming: Principles and Practice Using C++ (Bjarne Stroustrup) (updated for C++11/C++14) An introduction to programming using C++ by the creator of the language. A good read, that assumes no previous programming experience, but is not only for beginners.

Introductory, with previous programming experience

  • C++ Primer * (Stanley Lippman, Josée Lajoie, and Barbara E. Moo) (updated for C++11) Coming at 1k pages, this is a very thorough introduction into C++ that covers just about everything in the language in a very accessible format and in great detail. The fifth edition (released August 16, 2012) covers C++11. [Review]

  • A Tour of C++ (Bjarne Stroustrup) (EBOOK) The “tour” is a quick (about 180 pages and 14 chapters) tutorial overview of all of standard C++ (language and standard library, and using C++11) at a moderately high level for people who already know C++ or at least are experienced programmers. This book is an extended version of the material that constitutes Chapters 2-5 of The C++ Programming Language, 4th edition.

  • Accelerated C++ (Andrew Koenig and Barbara Moo) This basically covers the same ground as the C++ Primer, but does so on a fourth of its space. This is largely because it does not attempt to be an introduction to programming, but an introduction to C++ for people who've previously programmed in some other language. It has a steeper learning curve, but, for those who can cope with this, it is a very compact introduction into the language. (Historically, it broke new ground by being the first beginner's book to use a modern approach at teaching the language.) [Review]

  • Thinking in C++ (Bruce Eckel) Two volumes; is a tutorial style free set of intro level books. Downloads: vol 1, vol 2. Unfortunately they’re marred by a number of trivial errors (e.g. maintaining that temporaries are automatically const), with no official errata list. A partial 3rd party errata list is available at (http://www.computersciencelab.com/Eckel.htm), but it’s apparently not maintained.

* Not to be confused with C++ Primer Plus (Stephen Prata), with a significantly less favorable review.

Best practices

  • Effective C++ (Scott Meyers) This was written with the aim of being the best second book C++ programmers should read, and it succeeded. Earlier editions were aimed at programmers coming from C, the third edition changes this and targets programmers coming from languages like Java. It presents ~50 easy-to-remember rules of thumb along with their rationale in a very accessible (and enjoyable) style. For C++11 and C++14 the examples and a few issues are outdated and Effective Modern C++ should be preferred. [Review]

  • Effective Modern C++ (Scott Meyers) This is basically the new version of Effective C++, aimed at C++ programmers making the transition from C++03 to C++11 and C++14.

  • Effective STL (Scott Meyers) This aims to do the same to the part of the standard library coming from the STL what Effective C++ did to the language as a whole: It presents rules of thumb along with their rationale. [Review]


  • More Effective C++ (Scott Meyers) Even more rules of thumb than Effective C++. Not as important as the ones in the first book, but still good to know.

  • Exceptional C++ (Herb Sutter) Presented as a set of puzzles, this has one of the best and thorough discussions of the proper resource management and exception safety in C++ through Resource Acquisition is Initialization (RAII) in addition to in-depth coverage of a variety of other topics including the pimpl idiom, name lookup, good class design, and the C++ memory model. [Review]

  • More Exceptional C++ (Herb Sutter) Covers additional exception safety topics not covered in Exceptional C++, in addition to discussion of effective object oriented programming in C++ and correct use of the STL. [Review]

  • Exceptional C++ Style (Herb Sutter) Discusses generic programming, optimization, and resource management; this book also has an excellent exposition of how to write modular code in C++ by using nonmember functions and the single responsibility principle. [Review]

  • C++ Coding Standards (Herb Sutter and Andrei Alexandrescu) “Coding standards” here doesn't mean “how many spaces should I indent my code?” This book contains 101 best practices, idioms, and common pitfalls that can help you to write correct, understandable, and efficient C++ code. [Review]

  • C++ Templates: The Complete Guide (David Vandevoorde and Nicolai M. Josuttis) This is the book about templates as they existed before C++11. It covers everything from the very basics to some of the most advanced template metaprogramming and explains every detail of how templates work (both conceptually and at how they are implemented) and discusses many common pitfalls. Has excellent summaries of the One Definition Rule (ODR) and overload resolution in the appendices. A second edition is scheduled for 2017. [Review]


  • Modern C++ Design (Andrei Alexandrescu) A groundbreaking book on advanced generic programming techniques. Introduces policy-based design, type lists, and fundamental generic programming idioms then explains how many useful design patterns (including small object allocators, functors, factories, visitors, and multimethods) can be implemented efficiently, modularly, and cleanly using generic programming. [Review]

  • C++ Template Metaprogramming (David Abrahams and Aleksey Gurtovoy)

  • C++ Concurrency In Action (Anthony Williams) A book covering C++11 concurrency support including the thread library, the atomics library, the C++ memory model, locks and mutexes, as well as issues of designing and debugging multithreaded applications.

  • Advanced C++ Metaprogramming (Davide Di Gennaro) A pre-C++11 manual of TMP techniques, focused more on practice than theory. There are a ton of snippets in this book, some of which are made obsolete by typetraits, but the techniques, are nonetheless useful to know. If you can put up with the quirky formatting/editing, it is easier to read than Alexandrescu, and arguably, more rewarding. For more experienced developers, there is a good chance that you may pick up something about a dark corner of C++ (a quirk) that usually only comes about through extensive experience.

Reference Style - All Levels

  • The C++ Programming Language (Bjarne Stroustrup) (updated for C++11) The classic introduction to C++ by its creator. Written to parallel the classic K&R, this indeed reads very much alike it and covers just about everything from the core language to the standard library, to programming paradigms to the language's philosophy. [Review]

  • C++ Standard Library Tutorial and Reference (Nicolai Josuttis) (updated for C++11) The introduction and reference for the C++ Standard Library. The second edition (released on April 9, 2012) covers C++11. [Review]

  • The C++ IO Streams and Locales (Angelika Langer and Klaus Kreft) There's very little to say about this book except that, if you want to know anything about streams and locales, then this is the one place to find definitive answers. [Review]

C++11/14 References:

  • The C++ Standard (INCITS/ISO/IEC 14882-2011) This, of course, is the final arbiter of all that is or isn't C++. Be aware, however, that it is intended purely as a reference for experienced users willing to devote considerable time and effort to its understanding. As usual, the first release was quite expensive ($300+ US), but it has now been released in electronic form for $60US.

  • The C++14 standard is available, but seemingly not in an economical form – directly from the ISO it costs 198 Swiss Francs (about $200 US). For most people, the final draft before standardization is more than adequate (and free). Many will prefer an even newer draft, documenting new features that are likely to be included in C++17.

  • Overview of the New C++ (C++11/14) (PDF only) (Scott Meyers) (updated for C++1y/C++14) These are the presentation materials (slides and some lecture notes) of a three-day training course offered by Scott Meyers, who's a highly respected author on C++. Even though the list of items is short, the quality is high.

  • The C++ Core Guidelines (C++11/14/17/…) (edited by Bjarne Stroustrup and Herb Sutter) is an evolving online document consisting of a set of guidelines for using modern C++ well. The guidelines are focused on relatively higher-level issues, such as interfaces, resource management, memory management and concurrency affecting application architecture and library design. The project was announced at CppCon'15 by Bjarne Stroustrup and others and welcomes contributions from the community. Most guidelines are supplemented with a rationale and examples as well as discussions of possible tool support. Many rules are designed specifically to be automatically checkable by static analysis tools.

  • The C++ Super-FAQ (Marshall Cline, Bjarne Stroustrup and others) is an effort by the Standard C++ Foundation to unify the C++ FAQs previously maintained individually by Marshall Cline and Bjarne Stroustrup and also incorporating new contributions. The items mostly address issues at an intermediate level and are often written with a humorous tone. Not all items might be fully up to date with the latest edition of the C++ standard yet.

  • cppreference.com (C++03/11/14/17/…) (initiated by Nate Kohl) is a wiki that summarizes the basic core-language features and has extensive documentation of the C++ standard library. The documentation is very precise but is easier to read than the official standard document and provides better navigation due to its wiki nature. The project documents all versions of the C++ standard and the site allows filtering the display for a specific version. The project was presented by Nate Kohl at CppCon'14.

Classics / Older

Note: Some information contained within these books may not be up-to-date or no longer considered best practice.

  • The Design and Evolution of C++ (Bjarne Stroustrup) If you want to know why the language is the way it is, this book is where you find answers. This covers everything before the standardization of C++.

  • Ruminations on C++ - (Andrew Koenig and Barbara Moo) [Review]

  • Advanced C++ Programming Styles and Idioms (James Coplien) A predecessor of the pattern movement, it describes many C++-specific “idioms”. It's certainly a very good book and might still be worth a read if you can spare the time, but quite old and not up-to-date with current C++.

  • Large Scale C++ Software Design (John Lakos) Lakos explains techniques to manage very big C++ software projects. Certainly a good read, if it only was up to date. It was written long before C++98, and misses on many features (e.g. namespaces) important for large scale projects. If you need to work in a big C++ software project, you might want to read it, although you need to take more than a grain of salt with it. The first volume of a new edition is expected in 2015.

  • Inside the C++ Object Model (Stanley Lippman) If you want to know how virtual member functions are commonly implemented and how base objects are commonly laid out in memory in a multi-inheritance scenario, and how all this affects performance, this is where you will find thorough discussions of such topics.

  • The Annotated C++ Reference Manual (Bjarne Stroustrup, Margaret A. Ellis) This book is quite outdated in the fact that it explores the 1989 C++ 2.0 version - Templates, exceptions, namespaces and new casts were not yet introduced. Saying that however this is book goes through the entire C++ standard of the time explaining the rationale, the possible implementations and features of the language. This is not a book not learn programming principles and patterns on C++, but to understand every aspect of the C++ language.

From what I saw in this post I decided to start reading the book Effective C++.

But now that there are many new features because of C++11 and that a few of the good practices changed, I'm not sure whether or not it is actually a good idea. Has the advent of C++11 deprecated any of the advice contained in Effective C++? If so, which topics should I avoid?

This what Scott Meyers himself had to say about it on his own blog

Which may lead you to wonder whether the information and advice in this pre-C++0x edition of Effective C++ remains relevant. I'm pleased to report that it does. Surprisingly so, in fact. Having spent nearly two years steeped in the details of C++0x, I expected to groan a bit as I reviewed this book's table of contents with C++0x in mind. Surely some Items would be inappropriate. But the advice I found proved sound. Should C++0x developers prefer consts, enums, and inlines to #defines (Item 2)? They should. Should they prevent exceptions from leaving destructors (Item 8)? Certainly. Should they use objects to manage resources? Declare data members private? Consider alternatives to virtual functions? Factor parameter-independent code out of templates? (Items 13, 22, 35, and 44.) Yes, yes, yes, yes! My goal has always been for Effective C++'s table of contents to summarize the advice in the book, and that summary remains just as applicable to C++0x development as to “traditional” C++ development. C++0x is a bigger language, and in some ways it's a different one, but the core techniques for making effective use of “old” C++ are core for the effective use of C++0x, too.

This doesn't mean that this Effective C++ is a perfect match for C++0x. The book doesn't discuss features new to C++0x, so Items about making effective use of those features are missing. A C++0xified Effective C++ would certainly have Items devoted to move operations, to uniform initialization, and to lambda expressions, and it'd probably have an entire chapter on making effective use of the concurrency API. Such a book would also contain different examples, e.g., ones making use of auto variables, range-based for loops, in-class default initializers, as well as the occasional variadic template. To the extent that this book falls short in its support for C++0x, the errors are those of omission, not commission.

UPDATE: the new title Effective Modern C++ has been for sale since November 2014 from O'Reilly and Amazon (and many others that you can google for).

Can anyone explain the output of the following program:

#include <iostream>
using namespace std;

int main()
   int test = 0;
   cout << "First  character " << '1' << endl;
   cout << "Second character " << (test ? 3 : '1') << endl;

   return 0;

First character 1
Second character 49

But both the printf statements should print the same line.

cout will display value of (test ? 3 : '1') expression after deducing appropriate <<operator. In this case it is int, you can check it using nice trick that Scott Meyers propagated in his newest book:

template < typename T > class TD; // Type Displayer
int main()
  int test = 0;
  TD<decltype((test ? 3 : '1'))> xType; 

  return 0;

this generates error, which will also give you information of type of your expression:

main.cpp:6:34: error: aggregate 'TD<int> xType' has incomplete type and cannot be defined TD xType;

which is int. And static_cast<int>('1') is 49.

C++11 adds the ability for telling the compiler to create a default implementation of any of the special member functions. While I can see the value of deleting a function, where's the value of explicitly defaulting a function? Just leave it blank and the compiler will do it anyway.

The only point I can see is that a default constructor is only created when no other constructor exists:

class eg {
    eg(int i);
    eg() = default; 

But is that really better than how you do it now?

class eg {
    eg(int i);
    eg() {}

Or am I missing a use-case?

See Item 17 from Scott Meyer's great book "Effective Modern C++". It describes many conditions under which default copy constructors, copy operations, and move operations are generated (or NOT generated).

In other words, the compiler might not "do it anyway". But if the default special member function makes sense, the user could use the "default" keyword to explicitly tell the compiler to generate a default function that otherwise not be generated.

From the Things to Remember at the end of Item 17:

  • Move operations are generated only for classes lacking explicitly declared move operations, copy operations, or a destructor.

  • The copy constructor is generated only for classes lacking an explicitly declared copy constructor, and it’s deleted if a move operation is declared. The copy assignment operator is generated only for classes lacking an explicitly declared copy assignment operator, and it’s deleted if a move operation is declared. Generation of the copy operations in classes with an explicitly declared destructor is deprecated.

Imagine you have a number of overloaded methods that (before C++11) looked like this:

class MyClass {
   void f(const MyBigType& a, int id);
   void f(const MyBigType& a, string name);
   void f(const MyBigType& a, int b, int c, int d);
   // ...

This function makes a copy of a (MyBigType), so I want to add an optimization by providing a version of f that moves a instead of copying it.

My problem is that now the number of f overloads will duplicate:

class MyClass {
   void f(const MyBigType& a, int id);
   void f(const MyBigType& a, string name);
   void f(const MyBigType& a, int b, int c, int d);
   // ...
   void f(MyBigType&& a, int id);
   void f(MyBigType&& a, string name);
   void f(MyBigType&& a, int b, int c, int d);
   // ...

If I had more parameters that could be moved, it would be unpractical to provide all the overloads.

Has anyone dealt with this issue? Is there a good solution/pattern to solve this problem?


Herb Sutter talks about something similar in a cppcon talk

This can be done but probably shouldn't. You can get the effect out using universal references and templates, but you want to constrain the type to MyBigType and things that are implicitly convertible to MyBigType. With some tmp tricks, you can do this:

class MyClass {
    template <typename T>
    typename std::enable_if<std::is_convertible<T, MyBigType>::value, void>::type
    f(T&& a, int id);

The only template parameter will match against the actual type of the parameter, the enable_if return type disallows incompatible types. I'll take it apart piece by piece

std::is_convertible<T, MyBigType>::value

This compile time expression will evaluate to true if T can be converted implicitly to a MyBigType. For example, if MyBigType were a std::string and T were a char* the expression would be true, but if T were an int it would be false.

typename std::enable_if<..., void>::type // where the ... is the above

this expression will result in void in the case that the is_convertible expression is true. When it's false, the expression will be malformed, so the template will be thrown out.

Inside the body of the function you'll need to use perfect forwarding, if you are planning on copy assigning or move assigning, the body would be something like

    this->a_ = std::forward<T>(a);

Here's a coliru live example with a using MyBigType = std::string. As Herb says, this function can't be virtual and must be implemented in the header. The error messages you get from calling with a wrong type will be pretty rough compared to the non-templated overloads.

Thanks to Barry's comment for this suggestion, to reduce repetition, it's probably a good idea to create a template alias for the SFINAE mechanism. If you declare in your class

template <typename T>
using EnableIfIsMyBigType = typename std::enable_if<std::is_convertible<T, MyBigType>::value, void>::type;

then you could reduce the declarations to

template <typename T>
f(T&& a, int id);

However, this assumes all of your overloads have a void return type. If the return type differs you could use a two-argument alias instead

template <typename T, typename R>
using EnableIfIsMyBigType = typename std::enable_if<std::is_convertible<T, MyBigType>::value,R>::type;

Then declare with the return type specified

template <typename T>
EnableIfIsMyBigType<T, void> // void is the return type
f(T&& a, int id);

The slightly slower option is to take the argument by value. If you do

class MyClass {
    void f(MyBigType a, int id) {
        this->a_ = std::move(a); // move assignment

In the case where f is passed an lvalue, it will copy construct a from its argument, then move assign it into this->a_. In the case that f is passed an rvalue, it will move construct a from the argument and then move assign. A live example of this behavior is here. Note that I use -fno-elide-constructors, without that flag, the rvalue cases elides the move construction and only the move assignment takes place.

If the object is expensive to move (std::array for example) this approach will be noticeably slower than the super-optimized first version. Also, consider watching this part of Herb's talk that Chris Drew links to in the comments to understand when it could be slower than using references. If you have a copy of Effective Modern C++ by Scott Meyers, he discusses the ups and downs in item 41.

Item 26 from Scott Mayers's "Effective STL" is labeled "Prefer iterator to const_iterator, reverse_iterator and const reverse iterator".

The reasoning is that some forms of insert() and erase() require exactly iterator and converting from the other types is tedious and error-prone. Furthermore, comparing iterator and const_iterator could be problematic, depending on the STL implementation.

The book was released at 2001. Is the advice in Item 26 still valid with the current state of gcc?

The advice has been reversed, as can be seen from Item 13 of the upcoming Effective Modern C++ which is titled:

Prefer const_iterators to iterators

The reason is that C++11 and C++14 add several tweaks that make const_iterators a lot more practical:

C++11 adds

  • member functions cbegin() and cend() (and their reverse counterparts) for all Standard Library containers
  • member functions using iterators to identify positions (e.g. insert(), erase()) now take a const_iterator instead of an iterator

C++14 completes that by adding non-member cbegin() and cend() (and their reverse counterparts)

I've recently been learning C++ and just today have been introduced to const and the concept of const correctness. In an attempt to better understand the theory, I've been writing a series of simple programs to make sure that I understand the concept correctly. I thought I understood everything, but then when using the auto keyword in one of the programs, I seem to have got a bit stuck.

In order to test that I understood how const pointers work I wrote a simple program. I won't bother posting the whole thing since there's only two parts of it that are relevant. I have a class with a const data member of type int:

const int tryToChangeMe;

Within this class I also have a member function that returns a const pointer to the above const int:

const int* const MyClass::test()
    return &tryToChangeMe;

In my main function I then call the above function, making use of the auto keyword. In order to test that what I think I know about const is correct I then attempt to reassign the tryToChangeMe variable through the pointer. Like so:

auto temp = myClass.test();
*temp = 100;

As I expected, the program wouldn't compile due to the error that I caused when trying to assign a value to a const variable. However, I didn't just return a pointer to const, I returned a const pointer to a const (at least that's what I thought I did). So to test this, I attempted to reassign the pointer to a new memory address, quite confident that I'd get a similar compilation error:

temp = new int;

But quite confusingly the program compiled without any issue. Stepping through with the debugger revealed that sure enough, the pointer was losing its original address and being assigned a brand new one. Wondering what was going on, I just happened by chance to remove the auto keyword and replace it with the variable's full type:

const int* const temp = myClass.test();

Upon testing everything again, the results were as expected and this time I was not able to reassign the pointer to a new address.

So after all that I guess my question is, why? Why does the auto keyword allow you to bypass the const qualifier of pointers? Did I do something wrong?

By the way, I'm not sure if it matters but I'm using Visual Studio 2015 preview

When you write

auto temp = rhs;

type deduction works as follows:

  • if rhs is a reference, then the reference is ignored

  • the top-level cv(const-volatile)-qualifiers of rhs are also ignored (they are not ignored however if you do auto& temp = rhs;; in this case the compiler pattern-matches the type)

In your case, the type of the right hand side is

const int* const
           top-level cv qualifier

i.e. const pointer to const-int. The pointer is like any other variable, so it's const-ness will be discarded (technically, the top-level cv qualifier is const and it is discarded), hence you end up with the type of temp being deduced as

const int*

i.e. a non-const pointer to const-int, so it can be re-assigned. If you want to enforce the const-ness, then you have to declare the left hand side as

const auto temp = myClass.test();
need this

Scott Meyers has an excellent introduction to the subject (also available on his Effective Modern C++ book, Items 1 and 2 free to browse here), in which he explains how template type deduction works. Once you understand that, understanding auto is a breeze, since really auto type deduction mimic very closely the template type deduction system (with the notable exception of std::initializer_list<>).


There is an additional rule for

auto&& temp = rhs;

but to understand it you need to understand how forwarding (universal) references work and how reference collapsing works.

Especially in connection with std::vector it is important that types are noexcept movable when possible.

So when declaring a move constructor = default like in

struct Object1
    Object1(Object1 &&other) = default;

std::is_nothrow_move_constructible<Object1>::value will be true as every member (0 here) of Object1 is nothrow-move-constructible, which is answered here.

Yet what happens if the move copy constructor is only declared and then later = default defined like in the following code?

struct Object2
    Object2(Object2 &&other);
Object2::Object2(Object2 &&other) = default;

With g++ 4.9.2 std::is_nothrow_move_constructible<Object2>::value is false and I have to mark both the declaration and the definition as noexcept to make it true.

Now what I am interested in is what the actual rules are. Especially since Item 22 in Effective Modern C++ (Scott Meyers) seems to give ill advice by suggesting to implement the pimpl-idiom move constructor like I did with Object2.


If a function is explicitly defaulted on its first declaration,

  • it is implicitly considered to be constexpr if the implicit declaration would be, and,
  • it has the same exception specification as if it had been implicitly declared (15.4).

These rules do not apply if the function is explicitly defaulted on a later declaration, as in your later example, so instead, except for destructors, the function is considered noexcept(false) by default like most other functions.

Since the explicit defaulting can be in a different translation unit - and in the pimpl case, is in a different TU - there's no general way for the compiler to figure out after seeing the class definition only whether the move constructor will throw, unless the function is explicitly defaulted in the class definition (i.e., at its first declaration).

In his new book Effective Modern C++, Scott Meyers makes the statement in the section "Items 7: Distinguish between () and {} when creating objects," that:

I'll generally ignore the equals-sign-plus-braces syntax, because C++ usually treats it the same as the braces-only version.

Taking note of the "usually" qualifier, how does when and how does = { ... } differ from plain { ... }?

For a template function, we can specialize it as follows:

template <typename T>
void func(T t) {}

// specialization for int
template <>
void func(int t) {}

However, I'm not sure how to specialize a template function with universal reference (a name from Meyers' book).

// template function with universal reference
template <typename T>
void func(T &&t) {}

I think simply replacing T with int doesn't make it a specialization:

template <>
void func(int &&t) {}

Since the template function can accept both lvalue and rvalue, while the 'specialized' one can only accept rvalue.

Should I also define a 'specialization' with lvalue reference?

// 'specialization' for lvalue reference
template <>
void func(int &t) {}

And the two 'specializations' make the specialization for the original template function? Or does it make any sense to have a specialization for it?

Specializing function templates is rarely a good idea. Very rarely. It looks like a mixture of template class specialization and overloading, but works like neither.

Functions have overloads. Use those.

If overloading does not get the exact behaviour you want, use a helper function with tag dispatching based overloading, or forward to a class.

In this case, it could be as simple as:

template <typename T>
void func(T&&){}
void func(int){}


template<class T>struct tag_t{};
template<class T>constexpr tag_t<T>tag{};
namepsace details{
  template <class T, class U>
  void func(tag_t<T>, U&&){}
  template <class U>
  void func(tag_t<int>, U&&){}
template <class T>
void func(T&&t){
  return details::func(tag<std::decay_t<T>>, std::forward<T>(t));

I'm trying to understand C++11's universal references, and wrote the following code:

#include <cstdio>                                                                                                                                                                                                                                            

template <typename L, typename R>                                                                                                                                                                                                                            
static void Run(L&& lhs, const R& rhs) {                                                                                                                                                                                                                     
  lhs += rhs;                                                                                                                                                                                                                                                

static void Run2(int&& lhs, const int& rhs) {                                                                                                                                                                                                                
  lhs += rhs;                                                                                                                                                                                                                                                

int main() {                                                                                                                                                                                                                                                 
  int a = 0;                                                                                                                                                                                                                                                 
  int b = 3;                                                                                                                                                                                                                                                 
  Run(a, b);                                                                                                                                                                                                                                                 
  printf("%d\n", a);                                                                                                                                                                                                                                         
  // This does not compile.                                                                                                                                                                                                                                  
  Run2(a, b);                                                                                                                                                                                                                                                
  printf("%d\n", a);                                                                                                                                                                                                                                         
  return 0;                                                                                                                                                                                                                                                  

Note that Run() works, but the line calling Run2() will fail to compile. I can't really figure out why. The error I get is no known conversion from 'int' to 'int &&' for 1st argument.

I'm sure the compiler is right, but I can't figure out under why. It seems to be Run() and Run2() are doing the same things right?

Btw, changing Run2() to be templated with a single parameter also does not work.

The first one is a universal reference (as it described in the book of Scott Meyers Effective Modern C++) and the second one is rvalue reference

In order to make it work you need to call it like this:

Run2(std::move(a), b);