Q:

Copy constructor is not called whereas it should be

#include <iostream>
using namespace std;
class Base{
    int a;
public:
    Base(int b):a(b){cout<<"0"<<endl;}
    Base(Base const &b):a(b.a){cout<<"1"<<endl;}
private:
    Base(Base &b);
};
Base fun(){
    return 2;//
}
int main(){
    fun();
    return 0;
}

I think it will invoke Base(int b) to construct a  temporary object,then use
 Base(Base const &b),
so it will cout "0"and "1",but as the matter of fack that it only cout "0",why?

A:

The issue is called copy elision: under certain circumstances the compiler is allowed to elide copy (or move) construction of objects. Notably, whenever a temporary object (i.e., an object without a name) is copied the copy can be elided. The compiler is also allowed to elide the copy when returning a named value from a function. This is often referred to as [Named] Return Value Optimization or NRVO.
The circumstances where copies can be elided are (in the C++ standard you can find the details in section 12.8 [class.copy] paragraph 31):

when copying a temporary variable
when returning a local variable (but not a function argument) using its name
when throwing a local variable (but not a function argument) using its name
when catching an exception by value

Copy elision is specifically allowed even if applying this optimization changes the behavior of the program, i.e., when the copy (or move) constructor or the destructor have side-effects.

