Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the std::map default constructor explicit?

The following code compiles fine on g++ (various versions) but fails on clang++-3.4 with libc++ on my system:

#include <map>
#include <string>

std::map<std::string, std::string> f() {
    return {};
}

int main() {
    auto m = f();
}

clang marks the following problem:

x.cpp:6:12: error: chosen constructor is explicit in copy-initialization
    return {};
           ^~
/usr/local/Cellar/llvm34/3.4.2/lib/llvm-3.4/bin/../include/c++/v1/map:838:14: note: constructor declared here
    explicit map(const key_compare& __comp = key_compare())
             ^

Indeed, the include file declares the constructor as explicit. But it’s not marked as such in my C++11 draft standard. Is this a bug in clang++/libc++? I was unable to find a relevant bug report.

like image 638
Konrad Rudolph Avatar asked Jul 11 '17 09:07

Konrad Rudolph


1 Answers

There is no empty constructor before C++14. Default construction for std::map<Key, Value, Compare, Allocator> is marked explicit with 2 default parameters until C++14:

explicit map( const Compare& comp = Compare(), 
              const Allocator& alloc = Allocator() );

After C++14, we have a non-explicit empty default constructor which calls the explicit constructor from before (which now does not have a default Compare argument):

map() : map( Compare() ) {}
explicit map( const Compare& comp, 
              const Allocator& alloc = Allocator() );

So your example would only be valid after C++14.

Source: http://en.cppreference.com/w/cpp/container/map/map

like image 187
Thomas Russell Avatar answered Oct 10 '22 21:10

Thomas Russell