1

The following initialization,

auto p = std::make_pair(std::stringstream{}, "Hello World!");

compiles and works fine with clang++ using libc++.

Compiling it using libstdc++, however, gives error with both clang++ or g++,

error: use of deleted function 'std::basic_stringstream<char>::basic_stringstream(const std::basic_stringstream<char>&)'

from g++, and

error: call to implicitly-deleted copy constructor of 'std::basic_stringstream<char>'

from clang++ using libstdc++.

My understanding of the standard is that this type of declaration plus initialization should not involve copy constructor. Am I wrong? Should libc++ allow this kind of initialization? Or is libstdc++ not correct?

EDIT: after you kind replies, I know it is a bug in gcc, which won't be fixed until v5. Whether using copy initialization or direct initialization, calling make_pair always requires a move or copy constructor, which gives error under current buggy gcc. So my question is how to rewrite my code easily to circumvent the bug. I have a class hierarchy which has a member of type stringstream. Removing it would cause too much headache. Is using a unique_ptr the only way to go?

jxy
  • 784
  • 7
  • 16
  • probably libstdc++ has not been updated to c++11 – Cheers and hth. - Alf Feb 17 '15 at 16:27
  • 1
    @Cheersandhth.-Alf Looks like [gcc bug 54316](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316), which is supposed to be fixed in gcc 5 (o.O) – dyp Feb 17 '15 at 16:34
  • @Cheersandhth.-Alf: libstdc++ has had a _lot_ of C++11 in it for a very long time (in the order of eight years). But there are still a few holes. You don't tend to get the entire new standard in one go. – Lightness Races in Orbit Feb 17 '15 at 17:33

1 Answers1

2

That is copy-initialization, and there has to be an accessible constructor to transfer the converted value into the new object.

However, the move constructor should be selected. (assuming your copy of libstdc++ is new enough to provide one for std::pair)

In any case, it would be better to use direct-initialization:

auto p(std::make_pair(std::stringstream{}, "Hello World!"));
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • @dyp: I don't understand your question? Copy-initialization can select a move constructor since C++11. – Ben Voigt Feb 17 '15 at 16:29
  • @dyp: oh darn, you're right. Switched to `()`. – Ben Voigt Feb 17 '15 at 16:29
  • 2
    You know this already, but it might not be obvious to everyone: Direct-initialization in this case also requires a copy/move constructor, and has the same semantics here as copy-init. (It only allows using explicit ctors.) – dyp Feb 17 '15 at 16:32
  • g++ / libstdc++ still gives the same error with direct-initialization. – jxy Feb 17 '15 at 17:15