使用临时对象复制构造函数需要 [英] Copy Constructor Needed with temp object

查看:96
本文介绍了使用临时对象复制构造函数需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码仅在复制构造函数可用时工作。

The following code only works when the copy constructor is available.

当我添加打印语句(通过 std :: cout )并使复制构造函数可用时, (我假设有这样编译器欺骗发生删除不必要的副本)。

When I add print statements (via std::cout) and make the copy constructor available it is not used (I assume there is so compiler trick happening to remove the unnecessary copy).

但是在输出运算符< 和函数 plop 下面(我在其中创建一个临时对象)我看不到需要的复制构造函数。可以有人解释为什么语言需要它,当我通过const引用(或我做错了)一切。

But in both the output operator << and the function plop() below (where I create a temporary object) I don't see the need for the copy constructor. Can somebody explain why the language needs it when I am passing everything by const reference (or what I am doing wrong).

#include <iostream>

class N
{
    public:
        N(int)  {}
    private:
        N(N const&);
};

std::ostream& operator<<(std::ostream& str,N const& data)
{
    return str << "N\n";
}

void plop(std::ostream& str,N const& data)
{
    str << "N\n";
}

int main()
{
    std::cout << N(1);     // Needs copy constructor  (line 25)
    plop(std::cout,N(1));  // Needs copy constructor

    N    a(5);
    std::cout << a;
    plop(std::cout,a);
}

编译器:

[Alpha:〜/ X] myork%g ++ -v

使用内建规格。

目标:i686-apple-darwin10

配置:/ var / tmp / gcc / gcc-5646〜6 / src / configure --disable-checking --enable-werror --prefix = / usr --mandir = / share / man --enable -languages = c,objc,c ++,obj-c ++ --program-transform-name = / ^ [cg] [^ .-] * $ / s / $ / - 4.2 / --with-slibdir = / usr / lib --build = i686-apple-darwin10 --with-gxx-include-dir = / include / c ++ / 4.2.1 --program-prefix = i686-apple-darwin10- --host = x86_64-apple-darwin10 - target = i686-apple-darwin10

线程模型:posix

gcc版本4.2.1(Apple Inc. build 5646)

[Alpha:~/X] myork% g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5646~6/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5646)

[Alpha:〜/ X] myork%g ++ t.cpp

t.cpp:在函数'int main()'中:

t.cpp:10:error: 'N :: N(const N&)'是私人

t.cpp:25:错误:在此上下文中

t.cpp:10:error:'N :: N(const N&)'是私人

t.cpp:26:错误:在此上下文中

[Alpha:~/X] myork% g++ t.cpp
t.cpp: In function ‘int main()’:
t.cpp:10: error: ‘N::N(const N&)’ is private
t.cpp:25: error: within this context
t.cpp:10: error: ‘N::N(const N&)’ is private
t.cpp:26: error: within this context

这是一些实际代码的简化版本。

在实际代码中,我有一个包含std :: auto_ptr的类。这意味着一个复制构造函数接受一个const引用是无效的(没有一些工作),我得到一个错误,指示复制构造函数不可用,因为它:

This is a simplified version of some real code.
In the real code I have a class that contains a std::auto_ptr. This means that a copy constructor that takes a const reference is not valid (without some work) and I was getting an error indicating that the copy constructor was not available because of it:

更改类别:

class N
{
    public:
        N(int)  {}
    private:
        std::auto_ptr<int>  data;
};

错误是:


t.cpp:25:错误:没有匹配函数调用'N :: N(N)'

t.cpp:25: error: no matching function for call to ‘N::N(N)’


推荐答案

http://gcc.gnu.org/gcc-3.4 /changes.html


将类型为
的类型的右值绑定到引用时,副本构造函数
的类必须可访问。对于
实例,请考虑以下代码:

When binding an rvalue of class type to a reference, the copy constructor of the class must be accessible. For instance, consider the following code:



class A 
{
public:
  A();

private:
  A(const A&);   // private copy ctor
};

A makeA(void);
void foo(const A&);

void bar(void)
{
  foo(A());       // error, copy ctor is not accessible
  foo(makeA());   // error, copy ctor is not accessible

  A a1;
  foo(a1);        // OK, a1 is a lvalue
}




可能是令人惊讶的第一个
视线,特别是因为最流行的
编译器没有正确实现
这个规则(

This might be surprising at first sight, especially since most popular compilers do not correctly implement this rule (further details).

这将在C ++ 1x中修复问题391

This will be fixed in C++1x by Core Issue 391.

这篇关于使用临时对象复制构造函数需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆