Skip to content

cppreference Copy initialization

NOTE:

1、by-value的时候,都会涉及 Copy initialization

T object = other;
T object = {other} ; (until C++11)
f(other) when passing an argument to a function by value pass-by-value
return other; return-by-value
throw object;
catch (T object)
throw-by-value
T array[N] = {other};

Notes

Constructor

Copy-initialization is less permissive than direct-initialization: explicit constructors are not converting constructors and are not considered for copy-initialization.

struct Exp
{
    explicit Exp(const char*)
    {
    }
};

struct Imp
{
    Imp(const char*)
    {
    }
};

int main()
{
    // not convertible from const char*
    Exp e1("abc");  // OK
    Exp e2 = "abc"; // Error, copy-initialization does not consider explicit constructor

    // convertible from const char*
    Imp i1("abc");  // OK
    Imp i2 = "abc"; // OK
}
// g++ test.cpp -pedantic -Wall -Wextra --std=c++11

NOTE:

1、编译报错如下:

test.cpp: 在函数‘int main()’中:
test.cpp:19:11: 错误:请求从‘const char [4]’转换到非标量类型‘Exp
  Exp e2 = "abc"; // Error, copy-initialization does not consider explicit constructor

Implicit conversion and copy-initialization

Implicit conversion is defined in terms of copy-initialization: if an object of type T can be copy-initialized with expression E, then E is implicitly convertible to T.

In addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.

#include <string>

struct S
{
    S(std::string) // implicitly convertible from std::string
    {
    }
};


int main()
{
    S s1("abc"); // OK: conversion from const char[4] to std::string
    S s2 = "abc"; // Error: no conversion from const char[4] to S
    S s3 = "abc"s; // OK: conversion from std::string to S
}
// g++ test.cpp -pedantic -Wall -Wextra --std=c++11

NOTE:

1、编译报错如下:

test.cpp: 在函数‘int main()’中:
test.cpp:14:9: 错误:请求从‘const char [4]’转换到非标量类型‘S
  S s2 = "abc"; // Error: no conversion from const char[4] to S

Copy-initialization and move-initialization

If other is an rvalue expression, move constructor will be selected by overload resolution and called during copy-initialization. There is no such term as move-initialization.

Equals sign, =, in copy-initialization VS assignment operator overload

The equals sign, =, in copy-initialization of a named variable is not related to the assignment operator. Assignment operator overloads have no effect on copy-initialization.