[cfe-dev] C++11 error about initializing explicit constructor with {} ?

Benjamin Redelings benjamin.redelings at duke.edu
Fri Jan 18 08:32:13 PST 2013


On 01/18/2013 05:01 AM, James Dennett wrote:
> On Fri, Jan 18, 2013 at 1:49 AM, Csaba Raduly <rcsaba at gmail.com> wrote:
>> Hi Benjamin,
>>
>> On Thu, Jan 17, 2013 at 10:52 PM, Benjamin Redelings
>> <benjamin.redelings at duke.edu> wrote:
>>> Hi,
>>>
>>>      I'm trying to compile some of my C++11 code under clang-3.2; I
>>> originally wrote it under g++.  This is a case where g++-4.8 (snapshot)
>>> accepts my code, but clang-3.2 does not.  The error message is:
>>>
>>> In file included from ../../../master/src/mcmc/moves.C:20:
>>> In file included from ../../../master/src/mcmc/sample.H:26:
>>> ../../../master/src/mcmc/mcmc.H:390:94: error: chosen constructor is
>>> explicit in copy-initialization
>>>      std::set<int> get_affected_parameters(const
>>> owned_ptr<Probability_Model>&) const {return {};}
>>> ^~
>>> /usr/include/c++/v1/set:378:14: note: constructor declared here
>>>      explicit set(const value_compare& __comp = value_compare())
>>>
>>>
>>> So, basically, this code is trying to initialize a std::set<int> with {}.
>>> I'm not sure clang is right here, but I'm also not sure is wrong.  Can
>>> someone tell me, so I can possibly submit a bug report?
>> Maybe it's already fixed. The following code:
>>
>> #include <set>
>> std::set<int> getset() { return {}; }
>>
>> is compiled without errors by
>>
>> $ clang++ -v --std=c++0x setinit.cc
>> clang version 3.3 (trunk 172707)
>> Target: x86_64-unknown-linux-gnu
>> Thread model: posix
> You may be compiling against libstdc++, which has a C++11-compliance
> bug in that its default constructor for set is not explicit (while the
> standard specifies that it should be), which would make this compile
> when it should not.
>
> (On the other hand, I'm not sure that the standard _meant_ to specify
> that, or if it was just an accident.  Turning {} into an empty set
> seems like a rather pretty thing.)
>
> -- James
I don't think the issue is the standard library, and I'm not sure its 
fixed in clang 3.3.  I checked these combinations:

clang, libstdc++: yes
clang, libstdc++ modified to reflect the standard: NO
clang, libc++: NO

gcc, libstdc++: yes
gcc, libstdc++ modified to reflect the standard: yes.

Here "modifed to reflect the standard" means removing the constructor 
set::set(), and adding a default argument to the constructor
explicit set(const _Compare& __comp, const allocator_type& __a = 
allocator_type())
     to yield
explicit set(const _Compare& __comp=_Compare(), const allocator_type& 
__a = allocator_type())

So, it seems that libstdc++ is indeed wrong, but g++ accepts {} even 
when libstdc++ is fixed.

On the other hand, clang accepts {}, but only with the non-standard 
compliant libstdc++.

-BenRI



More information about the cfe-dev mailing list