2

I'm using this code:

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

void out(int* p){
    cout << *p;
}

int main(){
    vector<unique_ptr<int> > vInt;

    for(int i = 0; i < 10; i++)
        vInt.push_back(unique_ptr<int>(new int(i)));

    out(vInt[0].get()); // 0
    return 0;
}

If I use some online compiler it compiles OK but both C++ Builder XE2 and XE6 report errors:

[bcc32 Error] vector(1179): E2247 'unique_ptr<int,default_delete<int> >::unique_ptr(const unique_ptr<int,default_delete<int> > &)' is not accessible
[bcc32 Error] vector(1203): E2247 'unique_ptr<int,default_delete<int> >::unique_ptr(const unique_ptr<int,default_delete<int> > &)' is not accessible
[bcc32 Error] xutility(1682): E2247 'operator unique_ptr<int,default_delete<int> >::=(const unique_ptr<int,default_delete<int> > &)' is not accessible
[bcc32 Error] xutility(1552): E2247 'operator unique_ptr<int,default_delete<int> >::=(const unique_ptr<int,default_delete<int> > &)' is not accessible
[bcc32 Error] xmemory(28): E2247 'unique_ptr<int,default_delete<int> >::unique_ptr(const unique_ptr<int,default_delete<int> > &)' is not accessible

I use default compiler/IDE settings do I don't know why this happens?

Can someone having C++ Builder XE3 or later confirm this issue?

Tracer
  • 2,544
  • 2
  • 23
  • 58
  • 2
    Sounds like a bug in its standard library or treatment of prvalues? Try `vInt.emplace_back()` instead of `vInt.push_back()`. – tclamb May 02 '14 at 13:38
  • It does not recognize emplace_back method. Just tried it on XE6. Since the code above works on GNU GCC version 4.7.2 I don't see why it wouldn't work here. I think it's C++ Builder issue? – Tracer May 02 '14 at 13:41
  • That it would be. It would seem C++ Builder doesn't implement C++11. Sounds like you're stuck with `std::auto_ptr`. – tclamb May 02 '14 at 13:52
  • Already tried. Cannot use auto_ptr also. Both report errors at push_back. As far of implementation of C++11 Embarcadero states they support it from XE3 so I'm confused here... – Tracer May 02 '14 at 13:54
  • @tclamb - You can't use `auto_ptr` in a `vector`. – PaulMcKenzie May 02 '14 at 14:10
  • yes i can. GCC allows it. – Tracer May 02 '14 at 14:12
  • 2
    C++ Builder 32 bit is not C++11 compliant, the 64 bit compiler as as its based on Clang 3.1. If you can't use auto_ptr either, then there is something wrong in your install as auto_ptr works in both compilers. – Gregor Brandt May 02 '14 at 15:23
  • 1
    @Tracer You "can" use one in a standard container as in it'll probably compile, but it's undefined behavior. Specifically, its copy semantics wreck the exception safety guarantees. – tclamb May 02 '14 at 15:39
  • @Tracer - Please see here: http://stackoverflow.com/questions/7359276/why-vector-push-backauto-ptr-wouldnt-compile There is no guarantee that a vector of auto_ptr will even compile, let alone "work". – PaulMcKenzie May 02 '14 at 19:19
  • @GregorBrandt - you're right! It works in 64 bit applications. Thanks! – Tracer May 02 '14 at 19:36
  • @Tracer in that case I have made it an answer, for the points you know :-) – Gregor Brandt May 02 '14 at 21:29

3 Answers3

5

It's a compiler bug/failure to implement C++11 standards correctly. push_back has two overloads, one takes a const lvalue reference, another rvalue reference. Your code is perfectly fine since in vInt.push_back(unique_ptr<int>(new int(i))); the created unique_ptr is a temporary, which should be bound to rvalue reference and then moved into storage.

I don't have C++ builder so I don't know what workarounds will work. If it happens to implement emplace_back you can use that. Otherwise, you may instead resort to boost::container::vector or boost.ptr_container.

Siyuan Ren
  • 7,573
  • 6
  • 47
  • 61
2

I found the answer thanks to @GregorBrandt. C++ 11 is still not supported under 32 bit applications. Only for 64 bit.

https://forums.embarcadero.com/message.jspa?messageID=596431

http://qc.embarcadero.com/wc/qcmain.aspx?d=114889

Tracer
  • 2,544
  • 2
  • 23
  • 58
  • Adding C++11 support to bcc32 is actually the top-voted feature request on Embarcadero QC. I don't see it happening though, unless somehow they can use bcc64's front end with bcc32's back end. – M.M May 03 '14 at 03:01
  • Nope, but they did eventually release a separate C++11 32-bit compiler (bcc32c) that is based on clang instead of the old bcc32. – Remy Lebeau Jun 09 '17 at 17:31
  • Note that [QualityCentral has now been shut down](https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward), so you can't access `qc.embarcadero.com` links anymore. If you need access to old QC data, look at [QCScraper](http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/). – Remy Lebeau Jun 09 '17 at 17:31
2

C++Builder's 32-bit compiler does not support C++11 yet. Its 64-bit compiler does, as it is based on Clang 3.1. If you can't use auto_ptr either, then there is something wrong in your install as auto_ptr works in both compilers.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Gregor Brandt
  • 7,659
  • 38
  • 59