标签: copy-initialization

对 C++ 构造函数删除感到困惑

这是我的课

class A {
public:
    A(int);
    A(A const&) = delete;
    A& operator=(const A& a) = delete;
// etc.
};
Run Code Online (Sandbox Code Playgroud)

在另一个文件中,我可以像这样调用构造函数:

auto foo = A(123);
Run Code Online (Sandbox Code Playgroud)

这解决了复制构造函数而不是我期望的构造函数,为什么?

error C2280: 'mynamspace::A::A(const mynamespace::A &)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

c++ constructor initialization copy-initialization

3
推荐指数
1
解决办法
73
查看次数

为什么这里模板 Vector3<int> 无法转换为 Vector3<int>?

看起来很奇怪。在这里您可以看到错误消息是一种类型之间发生转换并且失败。如果我从 Vector3 的复制构造函数中删除显式修饰符,那就很好,没有错误。有人可以解释为什么吗?我很困惑。

template<typename T>
class Vector3 {
public:
    explicit Vector3(const Vector3& v) :x(v.x), y(v.y), z(v.z) {}
    Vector3() :x(0), y(0), z(0) {}
    T x, y, z;
};
template<typename T>
Vector3<T> getVec3() {
    return Vector3<T>(); //c2440 "return":cannot convert Vector3<int> to Vector3<int>
}
int main()
{   
    getVec3<int>();
}
Run Code Online (Sandbox Code Playgroud)

c++ templates explicit copy-initialization

3
推荐指数
1
解决办法
115
查看次数

显式和非显式构造函数

class Test
    {
    public:
        Test(int i) { cout<<"constructor called\n";}
        Test(const Test& t) { cout<<" copy constructor called\n";}
    };
 class Test1
        {
        public:
            Test1(int i) { cout<<"constructor called\n";}
            explicit Test1(const Test1& t) { cout<<" copy constructor called\n";}
        };

    int main()
    {
        Test t(0);  
        Test u = 0;
        //Test1 t1(0);   Line 1
        //Test1 u1 = 0;  Line 2

    }
Run Code Online (Sandbox Code Playgroud)

我观察到不同的输出。情况 1:当第 1 行和第 2 行被注释时,o/p 为:构造函数调用 构造函数调用

情况 2:当第 1 行和第 2 行取消注释时:则编译错误

有人可以解释一下输出及其原因吗?也有人可以告诉operator=是否实际上最终调用了复制构造函数。

c++ constructor explicit copy-constructor copy-initialization

2
推荐指数
1
解决办法
3065
查看次数

隐式类类型转换是使用复制构造函数吗?

以下来自我的C++书籍的引文:

当我们使用直接初始化时,我们要求编译器使用普通函数匹配来选择与我们提供的参数最匹配的构造函数.当我们使用复制初始化时,我们要求编译器将右侧操作数复制到正在创建的对象中,必要时转换该操作数.

对我来说,这个粗体位会产生一些模糊性.它使得听起来像右手操作数被转换为类类型,然后使用复制构造函数,例如;

string s = "hello";
Run Code Online (Sandbox Code Playgroud)

会成为...

string s = string("hello"); 
Run Code Online (Sandbox Code Playgroud)

它使用复制构造函数.如果这是真的那么我的测试程序;

#include <iostream>
using namespace std;

class A{
public:
    A(const A& b): data(b.data) { cout << "The first way" << endl;}
    A(const char* c): data(c) { cout << "The second way" << endl;}
    string data;

};
int main(){
    A first("hello");
    A second = "sup";
}
Run Code Online (Sandbox Code Playgroud)

应该产生"第二种方式,第二种方式,第一种方式".然而它反而打印出"第二种方式,第二种方式".从这里我可以得出结论它是使用const char*构造函数而不是复制构造函数.我会好的,除非后来说......

在复制初始化期间,允许编译器(但没有义务)跳过复制/移动构造函数并直接创建对象.也就是说,允许编译器重写

string null_book = "9-999-99999-9"; 
Run Code Online (Sandbox Code Playgroud)

string null_book("9-999-99999-9");
Run Code Online (Sandbox Code Playgroud)

但是,即使编译器省略了对复制/移动构造函数的调用,复制/移动构造函数也必须存在,并且必须在程序中的该点可访问(例如,非私有).

我不确定为什么复制构造函数甚至需要在这些示例中提及,否则

 string null_book = "9-999-99999-9"
Run Code Online (Sandbox Code Playgroud)

总是隐含地意味着仍然使用const char*构造函数?实际上,我不需要定义复制构造函数以使上述工作正常.但是,如果我将"const A&"构造函数设置为私有(其他公共),那么我的程序将无法运行.为什么必须为不涉及它的隐式转换定义复制构造函数?什么构造函数"string null_book …

c++ copy-constructor implicit-conversion copy-initialization copy-elision

2
推荐指数
1
解决办法
318
查看次数

删除复制构造函数中的 const

这是我最初所做的。

class A
{   public:
    A()         { std::cout << "\ndefault constructor";     }
    A(const A&) { std::cout << "\ncopy constructor";        }
    A(int)      { std::cout << "\nconversion constructor";  }
};

A a0;           // print default constructor
A a1(a0);       // print copy constructor       note : direct initialization
A a2 = a0;      // print copy constructor       note : copy initialization
A a3(123);      // print conversion constructor     note : direct initialization
A a4 = 123;     // print conversion constructor     note : copy initialization (create a …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor copy-initialization

2
推荐指数
1
解决办法
688
查看次数

直接初始化!=从不同类型转换时复制初始化?

我一直认为对于与类类型不匹配的类型 T 的直接初始化和复制初始化是绝对相等的。但我似乎误会了。如果我复制初始化(使用=),下面的代码不会编译,并且只有当我通过括号()直接初始化时才编译(在任何情况下,代码在终止时都不起作用,但这是一个不同的故事,与这个问题)。

演示

#include <future>
#include <cstdio>

int main()
{
    /* This doesn't compile */

    // std::packaged_task<int()> foo = []() -> int {
    //     return 10;
    // };

    /* This works */

    std::packaged_task<int()> foo([]() -> int {
        return 10;
    });

    auto fut = foo.get_future();
    foo();
    auto a = fut.get();
    printf("a == %d\n", a);
}
Run Code Online (Sandbox Code Playgroud)

错误:

<source>: In function 'int main()':
<source>:8:37: error: conversion from 'main()::<lambda()>' to non-scalar type 'std::packaged_task<int()>' requested
    8 |     std::packaged_task<int()> foo = []() -> …
Run Code Online (Sandbox Code Playgroud)

c++ copy-initialization packaged-task direct-initialization

2
推荐指数
1
解决办法
92
查看次数

C++拷贝初始化+隐式构造函数call = fail

这段代码:

class foo
{
    int x;
public:
    foo(int x) : x(x) { }
    int get() const { return x; }
    //...
};

class bar
{
    int x;
public:
    bar(const foo& x) : x(x.get()) { }
    int get() const { return x; }
    bar& operator =(const foo& rhs) { x = rhs.get(); return *this; }
    //...
};

void func()
{
    foo f = 3;
    bar b = 3;
    b = 7;
    //...
}
Run Code Online (Sandbox Code Playgroud)

在线上出错bar b = 3(g ++ 4.7.1 …

c++ constructor implicit-conversion copy-initialization c++11

1
推荐指数
1
解决办法
138
查看次数

直接初始化POD变量不起作用,但复制初始化在将变量推送到矢量时会起作用

为什么以下代码无法编译,而编译成功后的两个示例?我在Windows 7上使用VS 2008.


直接初始化POD(失败):

int pod();
std::vector<int> pods;
//pods.push_back(pod); // This will generate a compiler error
// Compile error: 1>c:\test.hpp(43) : error C2664: 'std::vector<_Ty>::push_back' : cannot convert parameter 1 from 'int (__cdecl *)(void)' to 'const int &'
Run Code Online (Sandbox Code Playgroud)

复制POD的初始化(成功:

int pod = int();
std::vector<int> pods;
pods.push_back(pod); // No error!
Run Code Online (Sandbox Code Playgroud)

c++ initialization copy-initialization

0
推荐指数
1
解决办法
177
查看次数